system info: OS X 10.10.5, Clang = Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn), cmake = 2.8.12.2
Suppose I have some simple file, main.cpp:
#include <stdio.h>
#include <vector>
#include <algorithm>
int main(void)
{
std::vector<int> v{1, 2, 3, 4};
int sum = std::accumulate(v.begin(), v.end(), 0);
printf("Sum = %d\n", sum);
return 0;
}
When I run "clang++ -stdlib=libc++ -std=c++11 main.cpp" I get error:
main.cpp:11:20: error: no member named 'accumulate' in namespace 'std'
int sum = std::accumulate(v.begin(), v.end(), 0);
When I look, using an IDE (Qt Creator), I see that the included header is /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm
when I look through my file system, I see that /usr/include/c++/4.2.1 exists with c++11 compliant headers.
Next, I use cmake to control larger builds (the above is just an example setup).
So here's a token CMakeLists.txt file for the above example:
project(c11Test)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_FLAGS "-stdlib=libc++ -std=gnu++11")
add_executable(${PROJECT_NAME} main.cpp)
Which, when I build, creates this output (excerpt):
[100%] Building CXX object CMakeFiles/c11Test.dir/main.cpp.o
/usr/bin/c++ -stdlib=libc++ -std=gnu++11 -o
CMakeFiles/c11Test.dir/main.cpp.o -c /Users/username/c11Test/main.cpp
/Users/username/c11Test/main.cpp:11:20: error: no member named
'accumulate' in namespace 'std'
int sum = std::accumulate(v.begin(), v.end(), 0);
~~~~~^ 1 error generated.
(whole output here):
I'm aware of this post, which seems to imply that all I need to do is just include these compiler flags. But that doesn't seem to work.
Furthermore, I probably need to build this on a variety of OS X computers at different versions, so I really wonder if there's a general solution I'm overlooking here?
Another friend provided the answer:
In my bigger program (not here posted, obv.) Something had included <numeric> in some kind of hidden way. When I went to compile on OSX, it was no longer included. I had thought <algorithm> was the necessary component, but clearly it wasn't. So just my error.
Related
I'm aware that C++20 is not fully supported (yet) by the compilers, but I really want to learn modules and other C++20 stuff.
Modules are supported in GCC11 and Clang-8+.
Compiler Support of C++20
I've installed Clang-10 on my Ubuntu, but it still gives me errors:
import <iostream>;
using namespace std;
int main(){
cout << "Hello world";
}
What am I doing wrong?
COMMANDS:
clang++ -Wall -std=c++2a -stdlib=libc++ -fimplicit-modules
-fimplicit-module-maps main.cpp -o main
clang++ -Wall -std=c++20 -stdlib=libc++ -fimplicit-modules
-fimplicit-module-maps main.cpp -o main
ERROR: fatal error: 'iostream' file not found
Although c++20 adds modules the c++20 standard library doesn't expose any modules.
Microsoft have implemented some standard library modules which may or may not match a future c++ standard: https://learn.microsoft.com/en-us/cpp/cpp/modules-cpp?view=msvc-160#consume-the-c-standard-library-as-modules. With these your example would be:
import std.core;
using namespace std;
int main(){
cout << "Hello world";
}
As far as I can see neither libc++ or libstdc++ have implemented any modules yet.
By default, gcc trunk use c++17, and clang trunk use c++14, so you have to say compiler, that you want to use c++20
If you are compiling your code in terminal by yourself, than add following flag
--std=c++2a
If you compile your code using Cmake, than add following to your CMakeLists.txt
set(CMAKE_CXX_STANDARD 20)
And if you compile in some IDE(Codeblocks or Visual studio), than somewhere in compiler settings put supporting c++20
trunk means "the main line of development", so this compiler version should be latest officially supported
I am trying run this code in Clion IDE. I want to use TBB library. I use C++ 11.
#include “tbb/blocked_range.h”
#include “tbb/parallel_for.h”
#include <vector>
const size_t SIZE = 10000000;
int main()
{
std::vector<double> myArray(SIZE);
tbb::parallel_for(tbb::blocked_range<size_t>(0, SIZE),
[&myArray](const tbb::blocked_range<size_t> &r)
{
for (size_t i = r.begin(); i != r.end(); i++)
Calculate(myArray[i]);
});
return 0;
}
from command line :
g++ task1.cpp -o task1 -std=c++11 -fopenmp -ltbb
this code work perfect.
But in Clion not.
I think problem in my CMakeLists.txt file.
What Clion tell me:
CMakeFiles/parallel.dir/main.cpp.o: In function `run':
/usr/include/tbb/parallel_reduce.h:148: undefined reference to `tbb::task_group_context::~task_group_context()'
/usr/include/tbb/parallel_reduce.h:148: undefined reference to `tbb::task_group_context::~task_group_context()'
CMakeFiles/parallel.dir/main.cpp.o:(.rodata+0xa0): undefined reference to `typeinfo for tbb::task'
CMakeFiles/parallel.dir/main.cpp.o:(.rodata+0x1c8): undefined reference to `tbb::task::note_affinity(unsigned short)'
CMakeFiles/parallel.dir/main.cpp.o: In function `tbb::task_group_context::task_group_context(tbb::task_group_context::kind_type, unsigned long)':
/usr/include/tbb/task.h:441: undefined reference to `tbb::task_group_context::init()'
...
CMakeLists.txt
cmake_minimum_required(VERSION 3.6)
project(parallel)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp -ltbb")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp main.cpp)
add_executable(parallel ${SOURCE_FILES})
How can I change my CMakeLists.txt file or I should do some else? Thanks for you help.
First, you have to make sure your TBB is setup correctly.
The current version of TBB is oneTBB. It is an open source project supported by Intel. The older version of TBB is here, but it sends you to the newer version, oneTBB. So, it is better to stay with the newer oneTBB.
There are two ways to get oneTBB: Either from the oneTBB Github source here (which is explained here) or from Intel oneTBB here.
I preferred Intel, since it provides a GUI installer (also provides apt for Linux). After installing oneTBB using the GUI, you have to set the environment which is explained here.
You should test you oneTBB settings by a simple code. Above web page here provides a sample code, which I wrapped with a main function for your convenience (note the included header oneapi/tbb.h):
test.cpp
#include <iostream>
#include "oneapi/tbb.h"
int main(){
int sum = oneapi::tbb::parallel_reduce(oneapi::tbb::blocked_range<int>(1,101), 0,
[](oneapi::tbb::blocked_range<int> const& r, int init) -> int {
for (int v = r.begin(); v != r.end(); v++ ) {
init += v;
}
return init;
},
[](int lhs, int rhs) -> int {
return lhs + rhs;
}
);
std::cout << sum << '\n';
return 0;
}
Compile it with (as explained here):
g++ -o test test.cpp $(pkg-config --libs --cflags tbb)
If your system (gcc, oneTBB and others) are setup properly, this should work.
When it comes to CLion, you will need CMakeLists.txt file. There are examples in the oneTBB GitHub page here. Open for example test_all folder with CLion as if you are opening a project. It should build from there. By looking at the cmake files of the example project, you can create you own cmake file.
Update:
Please look at this post and posts there from Intel for oneTBB.
I have prepared sample files for old TBB and oneTBB here for building with both command line GCC and CMAKE. CMAKE is the one required for CLion.
For CLion and the old version of TBB this would be a basic CMAKE file:
cmake_minimum_required(VERSION 3.xx)
project(testtbb)
set(CMAKE_CXX_STANDARD 17)
find_package(TBB REQUIRED)
add_executable(testtbb_long.out testtbb_long.cpp)
target_link_libraries(testtbb_long.out tbb)
Note that for linking the TBB library to the defined executable, you need to use target_link_libraries as:
target_link_libraries(executable-name.out tbb)
You should use a cmake test to find libtbb, which also sets the correct variables.
There is a FindTBB on github, which you can try to use.
My code:
#include <iostream>
#include <string>
int main()
{
std::string test = "45";
int myint = std::stoi(test);
std::cout << myint << '\n';
}
Gives me the compile error:
error: 'stoi' is not a member of 'std'
int myint = std::stoi(test);
^
However, according to here, this code should compile fine. I am using the line set(CMAKE_CXX_FLAGS "-std=c++11 -O3") in my CMakeLists.txt file.
Why is it not compiling?
Update: I am using gcc, and running gcc --version prints out:
gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010
In libstdc++, the definitions of stoi, stol, etc., as well as the to_string functions, are guarded by the condition
#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
I have had this fail on one platform before (namely Termux on Android), resulting in to_string not being available even with g++ 6.1 and the C++14 standard. In that case, I just did
#define _GLIBCXX_USE_C99 1
before including anything, and voilà, suddenly the functions existed. (You should put this first, or even on the command line, rather than just before including <string>, because another header may include <string> first, and then its include guards will keep it from ever seeing your macro.)
I did not investigate why this macro wasn't set in the first place. Obviously this is a cause for concern if you want your code to actually work (in my case I didn't particularly, but FWIW there were no problems.)
You should check if _GLIBCXX_USE_C99 is not defined, or if _GLIBCXX_HAVE_BROKEN_VSWPRINTF is defined (which may be the case on MinGW?)
std::stoi is a C++11 function. You have to use the -std=c++11 to enable it in both g++ and clang++. This is the actual issue, not a linking error or a specific preprocessor define.
$ cat test.cxx
#include <iostream>
#include <string>
int main()
{
std::string test = "45";
int myint = std::stoi(test);
std::cout << myint << '\n';
}
$ g++ -otest test.cxx
test.cxx: In Funktion »int main()«:
test.cxx:7:17: Fehler: »stoi« ist kein Element von »std«
int myint = std::stoi(test);
^
$ g++ -otest test.cxx -std=c++11
$ ./test
45
$
edit: I just saw that you used c++11. Are you sure that's making it into your compile options? Check the generated makefile and watch the executed commands to be certain.
Your version seems up to date, so there shouldn't be an issue. I think it may be related to gcc. Try g++ instead.(Most likely automatically linking issue. If you just run gcc on a C++ file, it will not 'just work' like g++ does. That's because it won't automatically link to the C++ std library, etc.). My second advise is try std::atoi.
# I have fixed the issue. std::stoi uses libstdc++. It is about The GNU Standard C++ Library. In gcc you have to link adding -lstdc++. However, in g++, libstdc++ is linked automatically.
using gcc and using g++
Pay attention how it is compiled
using g++: g++ -std=c++11 -O3 -Wall -pedantic main.cpp && ./a.out
using gcc: gcc -std=c++11 -O3 -Wall -pedantic -lstdc++ main.cpp && ./a.out
I think you should set flag like set(CMAKE_EXE_LINKER_FLAGS "-libgcc -lstdc++") (Not tested)
#include <cstdlib>
int myInt = std::atoi(test.c_str());
If you are using Cmake to compile, add line:
"add_definitions(-std=c++11)"
after find_package command.
Use 'set(CMAKE_CXX_STANDARD 11)' for Cmake
I am using CMake 2.8.11 and GCC 4.8.2. I was building some C++ code which used std::shared_ptr which built fine in MS VS 2012 but when I tried the same on RHEL6 using GCC 4.8.2, I promptly ran into the following error:
error: 'shared_ptr' is not a member of 'std'
I found this question with responses that I thought addressed and I promptly added -std=c++11 to my CMAKE_CXX_FLAGS, but I still keep running into the error. I add the flag in CMake simply using:
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" CACHE STRING "Add C++ 11 flags")
I set my custom compiler in CMake using:
SET(GCC_DIR "</path/to/custom>/gcc")
SET(CMAKE_CXX_COMPILER "${GCC_DIR}/bin/g++ CACHE FILEPATH "CXX compiler")
SET(CMAKE_C_COMPILER "${GCC_DIR}/bin/gcc CACHE FILEPATH "C compiler")
The include is
#include <memory>
which in turn has
#include <bits/shared_ptr.h>
which defines the shared_ptr class. So I'm not sure why I keep getting the error (and yes I cleared cached and rebuilt after adding the -std=c++11 compiler option). Any ideas are very much appreciated.
EDIT 1:
I created a simple program (main.cpp) as follows:
#include <memory>
#include <iostream>
int main() {
std::shared_ptr<int> pint = std::make_shared<int>();
std::cout << "Pint points to " << pint.get() << "\n";
return 0;
}
Then I built it using <path/to/custom/>g++ main.cpp -o prog and promptly ran into the same error (above). Next I did: <path/to/custom/>g++ -std=c++11 main.cpp -o prog and it compiles & runs OK. For my real application, I added the -std=c++11 flag to linker flags as well (in addition to compiler flags) in my CMake config system, but I still see the same error. Proceeding to check the CMakeCache to see if the flags are property registered, but any ideas are appreciated.
EDIT 2:
Suprisingly, I found in CMakeCache that the -std=c++11 flag is not being added to the CMAKE_CXX_FLAGS, etc. So this must have to do with the error. I am trying to fix it so that it actually takes this flag. Thanks all.
The answer confirms the hunch in EDIT 2 of my question. Apparently CMake 2.8.x is not appending to the variable CMAKE_CXX_FLAGS using the SET command using the syntax shown in my question (as per the documentation); I tried other variants of the SET command to append, to no avail.
So finally, instead of appending, I assigned separately for the case when C++11 is to be enabled and when it is to be disabled, as follows:
IF(USE_C++11)
...
ELSE(USE_C++11)
...
ENDIF(USE_C++11)
This worked fine. Thanks to #nos for the idea to make an isolated example.
I just (re)installed MinGW from scratch, with gcc 4.8.1 (the latest available), and the following program won't compile:
#include <iostream>
#include <string>
int main()
{
float f;
std::string s = "5.235";
f = std::stof(s);
std::cout << f << '\n';
}
Here's the command I use:
g++ -std=c++11 -o test test.cpp
I get this error:
test.cpp:8:9: error: 'stof' is not a member of 'std'
f = std::stof(s);
^
The file bits\basic_string.h which declares std::stof is included properly in the string header, and I checked bits\basic_string.h for std::stof's declaration, and it's there.
After a bit of Googling I did find some old patches for MinGW (4.6 - 4.7) but they seem irrelevant since I'm on gcc 4.8.
Any ideas? Thanks in advance.
Not sure about exact problem, but check mingw-w64 they have gcc 4.9.2 for now. It compiles your code just well. (But since the mingw-w64 project on sourceforge.net is moving to mingw-w64.org it's better to use mingw-w64.org)
Despite of it's name it provides compilers for both x86 and x64 targets.
Probably this should be a comment, not an answer.