I want to avoid typing "-std=c++11" on the command line every time. Is there any simple/direct solution to my question?
vendredi 1 juillet 2016
What happens when reassigning to a future that is not ready yet
During a code review, I came across a piece of code that basically boils down to this:
#include <iostream>
#include <future>
#include <thread>
int main( int, char ** )
{
std::atomic<int> x( 0 );
std::future<void> task;
for( std::size_t i = 0u; i < 5u; ++i )
{
task = std::async( std::launch::async, [&x, i](){
std::this_thread::sleep_for( std::chrono::seconds( 2u * ( 5u - i ) ) );
++x;
} );
}
task.get();
std::cout << x << std::endl;
return 0;
}
I was not quite sure whether
- it is guaranteed that all tasks are executed when printing out the result,
- whether the tasks would be executed one after another (i.e. the task assignment would be blocking) or not.
I could not answer that question from reading documentation on the internet, so I thought I would write the snippet above to find out what our compiler actually does.
Now, I found out that the answer of what gcc-5 does is indecisive and that made me even more curious: One would assume that the assignment is either blocking or non-blocking.
If it is blocking, the time taken by the program should basically be the sum of the time the individual tasks take to execute. The first one takes 10 seconds, the second 8, the third 6, the fourth 4 and the last 2 seconds. So in total it should take 10+8+6+4+2 = 30 seconds.
If it is non-blocking, it should take as long as the last task, i.e. 2 seconds.
Here is what happens: It takes 18 seconds (measured using time ./a.out or a good old clock). By playing around a bit with the code I found out that the code behaves as if the assignment would be alternatingly blocking and non-blocking.
But this can't be true, right? std::async probably falls back to std::deferred half of the time? My debugger says that it spawns two threads, blocks until both threads exit, then spawns two more threads and so on.
What does the standard say? What should happen? What happens inside gcc-5?
partial class template specialisation for std::vector of fundamental types
I would like to partially specialise a class template for std::vector containing fundamental types.
My approach looks like this, but does not compile
#include <type_traits>
#include <vector>
#include <string>
#include <iostream>
template <typename T, bool bar = false>
struct foo {
static void show()
{
std::cout << "T" << std::endl;
}
};
template <typename T>
struct foo<typename std::enable_if<std::is_fundamental<T>::value, std::vector<T>>::type, false> {
static void show()
{
std::cout << "std::vector<fundamental type>" << std::endl;
}
};
template <typename T>
struct foo<std::vector<T>, false> {
static void show()
{
std::cout << "std::vector<T>" << std::endl;
}
};
int main()
{
foo<int>::show();
foo<std::vector<int>>::show();
foo<std::vector<std::string>>::show();
}
How can I make it work?
Accept move-only parameter by value or rvalue reference
The accepted answer of this post Pass by value vs pass by rvalue reference says that:
For move-only types (as
std::unique_ptr), pass-by-value seems to be the norm...
I'm a little bit doubtful about that. Let's say there is some non-copyable type, Foo, which is also not cheap to move; and some type Bar that has a member Foo.
class Foo {
public:
Foo(const Foo&) = delete;
Foo(Foo&&) { /* quite some work */ }
...
};
class Bar {
public:
Bar(Foo f) : f_(std::move(f)) {} // (1)
Bar(Foo&& f) : f_(std::move(f)) {} // (2)
// Assuming only one of (1) and (2) exists at a time
private:
Foo f_;
};
Then for the following code:
Foo f;
...
Bar bar(std::move(f));
Constructor (1) incurs 2 move constructions, while constructor (2) only incurs 1. I also remember reading in Scott Meyers's Effective Modern C++ about this but can't remember which item immediately.
So my question is, for move-only types (or more generally, when we want to transfer the ownership of the argument), shouldn't we prefer pass-by-rvalue-reference for better performance?
C++ Function using function pointers, but not as parameters
I am learning C++. Suppose I have two functions defined outside main():
double K(const double &x)
{
double am {1};
double gm {sqrt(1 - x)};
double temp {0};
for (int i=0; i<6; ++i)
{
temp = am;
am = (am + gm) * 0.5;
gm = sqrt(temp * gm);
}
return PI / (am + gm);
}
and:
double sn(const double &u, const double &m)
{
double Km {K(m)};
double qm {exp(-PI * K(1 - m) / Km)};
double numer {sin(PI * u * 0.5 / Km)};
double denom {0.5};
for (short i=1; i<5; ++i) // i < desired_nr_of_terms
{
numer += pow(-1, i) * pow(qm, i*(i + 1)) * sin((i + 0.5) * PI * u / Km);
denom += pow(-1, i) * pow(qm, i*i) * cos(i * PI * u / Km);
}
return pow(qm / m, 0.25) * numer / denom;
}
Would it be an improvement to call K() as a function pointer (say pntK)? The catch is that the parameter passed to K() is the same m passed to sn(), and that m is used, solo, too, inside sn(). If yes, please read further, else thank you. :-)
Do I have to make a typedef or std::function outside main() for this? Wouldn't that count as a global definition (which, as I understand, is something to avoid)?
Or, if the above is not a choice, I can define the alias (as I tried it) inside the sn() function, but then there are other functions that use pntK, how to deal with those? Define pointers inside each functions? That doesn't sound like a sane choice.
Or, if I want to pass the function pointer as a parameter to sn(), how do I deal with the fact that that both sn() and K() (or pntK()) make use of m? Would this be an "orthodox" choice?:
sn(const double &u, const double &m, std::function<double(const double&)> pntK(const double &m) = K)
If yes, then would it be safe to use it for the other functions that use K()? If not, what other choices are there?
Writing To & Reading From an Array using For Loops and User Input
#include <iostream>
using namespace std;
int arr[100] = {};
int terms;
int maxterms;
int temp;
int sum = 0;
int main() {
cout << "How many terms would you like to add?" << endl;
cin >> terms;
terms = maxterms;
for (int x = terms; x >= 0; x--) {
cout << "Number " << (((maxterms)-x) + 1) << ": ";
cin >> temp;
arr[(maxterms - x)] = temp;
cout << endl;
}
for (int x = 0; x < maxterms; x++) {
sum += arr[x];
}
cout << "Your sum is: " << sum;
return 0;
}
This simple program always prints sum as zero, and only prompts for user input once. How can this code be improved so that it writes to consecutive indexes of the array, then returns the sum of them?
Error while pushing elements to a vector inside a lambda function
Below lines of code give error:
std::vector<std::string> strVect;
auto pushToVector = [strVect] () {
strVect.push_back(std::string("Hi"));
};
pushToVector ();
ERROR:
2 overloads have no legal conversion for 'this' pointer
But when I pass strVect by reference in lambda there is no error.
std::vector<std::string> strVect;
auto pushToVector = [&strVect] () {
strVect.push_back(std::string("Hi"));
};
pushToVector ();
NO ERROR
Please let me know why do we get error in fist scenario?