I guess it's pretty self explanatory - I can't seem to use C++11 features, even though I think I have everything set up properly - which likely means that I don't.
Here's my code:
#include <cstdlib>
#include <iostream>
class Object {
private:
int value;
public:
Object(int val) {
value = val;
}
int get_val() {
return value;
}
void set_val(int val) {
value = val;
}
};
int main() {
Object *obj = new Object(3);
std::unique_ptr<Object> smart_obj(new Object(5));
std::cout << obj->get_val() << std::endl;
return 0;
}
Here's my version of g++:
ubuntu#ubuntu:~/Desktop$ g++ --version
g++ (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Here's how I'm compiling the code:
ubuntu#ubuntu:~/Desktop$ g++ main.cpp -o run --std=c++11
main.cpp: In function ‘int main()’:
main.cpp:25:2: error: ‘unique_ptr’ is not a member of ‘std’
main.cpp:25:24: error: expected primary-expression before ‘>’ token
main.cpp:25:49: error: ‘smart_obj’ was not declared in this scope
Note that I've tried both -std=c++11 and -std=c++0x to no avail.
I'm running Ubuntu 12.04 LTS from a flash drive on an Intel x64 machine.
You need to include header where unique_ptr and shared_ptr are defined
#include <memory>
As you already knew that you need to compile with c++11 flag
g++ main.cpp -o run -std=c++11
// ^
So here what I learned in 2020 - memory.h is at /usr/include AND in /usr/include/c++/4.8.5 and you need the second to be found before the first.
In Eclipse set the order using Project->Properties->Path and Symbols->Includes->Add... path if needed and set first
You need to include #include that will solve the problem, at least on my ubunto linux machine
Related
Looking for code to implement numpy's arange function in c++, I found this answer.
I placed the following code in a file test_arange_c.cpp:
#include <vector>
template<typename T>
std::vector<T> arange(T start, T stop, T step = 1)
{
std::vector<T> values;
for (T value = start; value < stop; value += step)
values.push_back(value);
return values;
}
int main()
{
double dt;
dt = 0.5;
auto t_array = arange<double>(0, 40, dt);
return 0;
}
When I try to compile it, I get the following error:
$ c++ test_arange_c.cpp -o test_arange_c.out
test_arange_c.cpp: In function ‘int main()’:
test_arange_c.cpp:14:8: error: ‘t_array’ does not name a type
auto t_array = arange<double>(0, 40, dt);
Without doubt, I've made a mistake that will be obvious to seasoned c++ users. But, after searching Google for a while, I haven't come up with what it is.
As #Brian suggested, I had not enabled C++11 support.
$ c++ --version
c++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This fails:
$ c++ test_arange_c.cpp -o test_arange_c.out
test_arange_c.cpp: In function ‘int main()’:
test_arange_c.cpp:16:8: error: ‘t_array’ does not name a type
auto t_array = arange<double>(0, 40, dt);
^
This works:
$ c++ -std=c++11 test_arange_c.cpp -o test_arange_c.out
$
I understand that if a temporary is bound to a reference member in the constructor's initializer list, the object will be destroyed as the constructor returns.
However, consider the following code:
#include <functional>
#include <iostream>
using callback_func = std::function<int(void)>;
int
func(const callback_func& callback)
{
struct wrapper
{
const callback_func& w_cb;
wrapper(const callback_func& cb) : w_cb {cb} { }
int call() { return this->w_cb() + this->w_cb(); }
};
wrapper wrp {callback};
return wrp.call();
}
int
main()
{
std::cout << func([](){ return 21; }) << std::endl;
return 0;
}
This looks perfectly valid to me. The callback object will live during the whole execution of the func function and no temporary copy should be made for wrapper's constructor.
Indeed, GCC 4.9.0 compiles fine with all warnings enabled.
However, GCC 4.8.2 compiler gives me the following warning:
$ g++ -std=c++11 -W main.cpp
main.cpp: In constructor ‘func(const callback_func&)::wrapper::wrapper(const callback_func&)’:
main.cpp:12:48: warning: a temporary bound to ‘func(const callback_func&)::wrapper::w_cb’ only persists until the constructor exits [-Wextra]
wrapper(const callback_func& cb) : w_cb {cb} { }
^
Is this a false positive or am I misunderstanding the object lifetimes?
Here are my exact compiler versions tested:
$ g++ --version
g++ (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ --version
g++ (GCC) 4.9.0 20140604 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This is a bug in gcc 4.8 that has been fixed in 4.9. Here is the bug report:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50025
As pointed out by Howard Hinnant and already indicated by R Sahu's comment, this is a bug (which used to be required by the then-broken standard; thanks to Tony D for pointing this out) in the way GCC 4.8 is treating initializer lists.
Changing the constructor in my original example from
wrapper(const callback_func& cb) : w_cb {cb} { }
to
wrapper(const callback_func& cb) : w_cb (cb) { }
makes the warning with GCC 4.8.3 go away and the created executable Valgrind clean. The diff of the two assembly files is huge so I don't post it here. GCC 4.9.0 creates identical assembly code for both versions.
Next, I replaced the std::function with a user-defined struct and deleted copy and move constructors and assignment operators. Indeed, with GCC 4.8.3, this retains the warning but now also gives a (slightly more helpful) error that the above line of code calls the deleted copy constructor of the struct. As expected, there is no difference with GCC 4.9.0.
I am testing an example code to implement bind(func,_1,_2) function. the code is the following:
#include <functional>
#include <iostream>
using namespace std;
using namespace std::placeholders;
int multiply(int a, int b)
{
return a * b;
}
int main()
{
auto f = bind(multiply, 5, _1);
for (int i = 0; i < 10; i++)
{
cout << "5 * " << i << " = " << f(i) << endl;
}
return 0;
}
a very simple code which should just return the first 9 multiples of 5.
Now, I've update my gcc compiler (basically removed the old one and went through the ordinary installation process, going from 4.2.1 to 4.6 - don't know why it didn't download the latest directly...) but I'm not sure if the g++ command is using the latest. if I press
g++ --version
I get
g++ (GCC) 4.6.0
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
however, when I try to compile my code, this is what I get:
test.cpp:5:17: error: ‘placeholders’ is not a namespace-name
test.cpp:5:29: error: expected namespace-name before ‘;’ token
test.cpp: In function ‘int main()’:
test.cpp:14:10: error: ‘f’ does not name a type
test.cpp:17:44: error: ‘f’ was not declared in this scope
I don't get it. the namespace should be within the header, and the header should be within the version of gcc I have (4.6.0), and yet I still get compilation errors
help pleeeease, this thing is driving me crazy :(
Okay, so I have
tmp.cpp:
#include <string>
int main()
{
std::to_string(0);
return 0;
}
But when I try to compile I get:
$ g++ tmp.cpp -o tmp
tmp.cpp: In function ‘int main()’:
tmp.cpp:5:5: error: ‘to_string’ is not a member of ‘std’
std::to_string(0);
^
I'm running g++ version 4.8.1. Unlike all the other references to this error that I found out there, I am not using MinGW, I'm on Linux (3.11.2).
Any ideas why this is happening? Is this standard behaviour and I did something wrong or is there a bug somewhere?
you may want to specify the C++ version with
g++ -std=c++11 tmp.cpp -o tmp
I don't have gcc 4.8.1 at hand , but in older versions of GCC,
you can use
g++ -std=c++0x tmp.cpp -o tmp
At least gcc 4.9.2 I believe also support part of C++14 by specifying
g++ -std=c++1y tmp.cpp -o tmp
Update:
gcc 5.3.0 (I am using the cygwin version) supports both -std=c++14 and -std=c++17 now.
to_string works with the latest C++ versions like version 11. For older versions you can try using this function
#include <string>
#include <sstream>
template <typename T>
std::string ToString(T val)
{
std::stringstream stream;
stream << val;
return stream.str();
}
By adding a template you can use any data type too.
You have to include #include<sstream> here.
i'm in a situation with a declaration of vector<vector<string>>. On windows it's ok i can declare this in a struct like vector<vector<string>>v={{"me","you"}} but on a linux machine..only errors so i must declare it after the struct initialization but how because mystruct.vec[0]={"me","you"} gives me a segmentation fault. Any sugestions please?
This program on gcc 4.7.2 works just fine:
#include <vector>
#include <string>
#include <utility>
#include <iostream>
using ::std::vector;
using ::std::string;
using ::std::move;
vector<vector<string>> foo()
{
vector<vector<string>>v={{"me","you"}};
return move(v);
}
int main()
{
using ::std::cout;
cout << "{\n";
for (auto &i: foo()) {
cout << " {\n";
for (auto &o: i) {
cout << " \"" << o << "\",\n";
}
cout << " },\n";
}
cout << "}\n";
return 0;
}
It produces this output:
$ /tmp/a.out
{
{
"me",
"you",
},
}
I think your problem is either an old compiler or that you have some other problem in some other place in your code.
I used this command line to compile:
$ g++ -std=gnu++0x -march=native -mtune=native -Ofast -Wall -Wextra vvstr.cpp
And my g++ gives this as a version:
$ g++ --version
g++ (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This page tells you which version of gcc has which C++ feature:
http://gcc.gnu.org/projects/cxx0x.html
If you are using GCC, them you need a version that supports this C++11 initialization feature, and then you need to tell the compiler to compile in C++11 mode by passing it the -std=c++0x flag (or =std=c++11 for the 4.7 series). See this demo, compiled with GCC 4.7.2:
#include <vector>
#include <string>
int main()
{
std::vector<std::vector<std::string>> v = {{"me","you"}};
}