I'm trying to convert a vector of boost::filesystem::path
to std::string
, using the member function string()
. I wrote this and it was working fine on Windows (MSVC 14, 2015):
std::transform(
users.begin(), users.end(), std::back_inserter(usersStrs),
std::mem_fn(static_cast<const std::string (PathType::*)() const>(
&PathType::string)));
Now I moved to gcc (6.3, Debian Stretch), and my code gave linking error that the signature above doesn't exist. To fix it, I had to change the code to:
std::transform(
users.begin(), users.end(), std::back_inserter(usersStrs),
std::mem_fn(static_cast<const std::string& (PathType::*)() const>(
&PathType::string)))
PS: I know a lambda solution is easier, which I now switched to, out of necessity.
At first, I thought MSVC is more tolerant, but then I switched back to Windows and got the opposite linking error, that the first signature is correct. I went to the source code (1.64, path.hpp
), and this is what I found:
# 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
So the reasoning I see is that on Windows, since it doesn't use UTF-8 by default, there's a temporary conversion. But why wouldn't boost use the same API for both Windows and Linux? Worst case, it'll cost a copy of a string. Right?
Is there an alternative to path::string()
that I should be using to have cross-platform API stability?