メンバー関数string()
を使用してboost::filesystem::path
のベクトルをstd::string
に変換しようとしています。私はこれを書いて、それは、Windows(MSVC 14、2015)に罰金働いていた:これはboost :: filesystemのバグですか? boost :: filesystem :: path :: string()がWindowsとLinuxで同じシグネチャを持っていないのはなぜですか?
std::transform(
users.begin(), users.end(), std::back_inserter(usersStrs),
std::mem_fn(static_cast<const std::string (PathType::*)() const>(
&PathType::string)));
は、今私は、GCC(6.3、Debianのストレッチ)に移動し、そして私のコードは、上記の署名が存在しないというリンクエラーが発生しました。
std::transform(
users.begin(), users.end(), std::back_inserter(usersStrs),
std::mem_fn(static_cast<const std::string& (PathType::*)() const>(
&PathType::string)))
PS:それを修正するために、私は、コードを変更しなければならなかった私は、私が今必要性から、に切り替えており、ラムダソリューションは簡単です知っています。
最初は、MSVCの方が耐性があると思っていましたが、Windowsに切り替えて、最初の署名が正しいという反対のリンクエラーが発生しました。私は、ソースコード(1.64、path.hpp
)に行って、これは私が見つけたものです:それは、デフォルトでUTF-8を使用していないので、
# ifdef BOOST_WINDOWS_API
const std::string string() const
{
std::string tmp;
if (!m_pathname.empty())
path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
tmp);
return tmp;
}
//...
# else // BOOST_POSIX_API
// string_type is std::string, so there is no conversion
const std::string& string() const { return m_pathname; }
//...
# endif
は、だから私が見る理由は、Windows上でそれで、あります一時的な変換。しかし、なぜWindowsとLinuxの両方で同じAPIを使用しないでください。最悪の場合、文字列のコピーが必要になります。右?
path::string()
の代わりに、クロスプラットフォームAPIの安定性を使用する必要がありますか?
なぜあなたは最初に 'static_cast <>'が必要なのですか? – Frank
@Frank 'path :: string()'のオーバーロードが異なるシグネチャを持っているので、それがなければ動作しません。使用する署名を定義する必要があります。 –
これは、ウィンドウ上のパスが2バイトのUTF-16ワイド文字として格納されているためです。:: Linuxへの変換は必須ですが、Linuxではutf-8文字として保存されますか?私は、この特定の変換方法のトレードオフは、いくつかのパス操作が実行されるたびに、ストリングを前後に変換することのトレードオフよりも優れていることを意味しますか? – VTT