dimanche 28 décembre 2014

Clang: Trouble using bind or mem_fn with string::c_str and transform

Trying to convert a vector of std::string to a vector of const char*:



std::vector<std::string> values;
values.push_back("test1");
values.push_back("test2");
values.push_back("test3");

std::vector<const char*> c_values(values.size());

// Option 1: Using mem_fn: Links correctly using g++/Linux, fails to link using clang/OSX
std::transform(values.begin(), values.end(), c_values.begin(), std::mem_fn(&std::string::c_str));

// Option 2: Using bind: Links correctly using g++/Linux, fails to link using clang/OSX
std::transform(values.begin(), values.end(), c_values.begin(), std::bind(&std::string::c_str, std::placeholders::_1));

// Option 3: Using lambda: Links correctly using both g++/Linux and clang/OSX
std::transform(values.begin(), values.end(), c_values.begin(), [](const std::string& str) { return str.c_str(); });


When compiling with g++ (4.7.2), all three options compile and link fine. When compiling with clang (6.0), options 1 and 2 fail to link, producing:



Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::c_str() const", referenced from:
json::json<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) in json.o
ld: symbol(s) not found for architecture x86_64


I am finding I need to use the lambda version (option 3) if I want it to link correctly across platforms using both g++ and clang. Am I running into a linker bug or a hole in clang's C++11 support, or is there something wrong with how I'm invoking the mem_fn() and bind() versions?


Aucun commentaire:

Enregistrer un commentaire