5

std::string のベクトルを const char* のベクトルに変換しようとしています:

#include <algorithm>
#include <functional>
#include <string>
#include <vector>

int main(int argc, char** argv)
{
    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());

    std::transform(values.begin(), values.end(), c_values.begin(), std::mem_fn(&std::string::c_str));
    std::transform(values.begin(), values.end(), c_values.begin(), std::bind(&std::string::c_str, std::placeholders::_1));
    std::transform(values.begin(), values.end(), c_values.begin(), [](const std::string& str) { return str.c_str(); });

    return 0;
}

g++ (4.7.2) でコンパイルすると、3 つのオプションすべてが正常にコンパイルおよびリンクされます。clang でコンパイルすると、オプション 1 と 2 がリンクに失敗し、次のようになります。

$ clang -std=c++11 -stdlib=libc++ -lc++ stringtransform.cpp 
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:
    _main in stringtransform-ff30c1.o
ld: symbol(s) not found for architecture x86_64

g++ と clang の両方を使用してプラットフォーム間で正しくリンクするには、ラムダ バージョン (オプション 3) を使用する必要があることがわかりました。リンカーのバグや、clang の C++11 サポートの穴に遭遇したのでしょうか、それとも mem_fn() および bind() バージョンの呼び出し方法に何か問題がありますか?

編集:

最新の Xcode (6.3.2、clang バージョン 6.1.0:

$ clang -v
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
4

3 に答える 3

0

これは libc++ の問題のようです。

これを考えると、

#include <string>
#include <iostream>

using namespace std;

int main(int argc, char** argv)
{
  string s("Hello, World!");
  const char * (std::string::*mem_c_str) () const = &std::string::c_str;
  cout << (s.*mem_c_str)() << endl;
  return 0;
}

同じエラーが発生します。

を使用することで固定され-stdlib=libstdc++ -lstdc++ます。どの-Onフラグでも機能するようです。

于 2015-06-18T00:02:46.367 に答える