Is this a bug in boost :: filesystem? Why doesn't boost :: filesystem :: path :: string () have the same signature on Windows and Linux?

I am trying to convert a vector boost::filesystem::pathto std::stringusing a member function string(). I wrote this and it worked perfectly 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 switched to gcc (6.3, Debian Stretch) and my code gave a link to the error that the signature above does not exist. To fix this, 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 that the lambda solution is simpler, and I switched to it as needed.

At first, I thought MSVC was more tolerant, but then I switched to Windows and got the opposite communication error that the first signature is correct. I went to the source code (1.64, path.hpp), and here 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

, , Windows, UTF-8 , . API Windows Linux? . ?

path::string(), API?

+4
2

, Boost.Filesystem. Boost 1.64 , :

string string(const codecvt_type& cvt=codecvt()) const;

; , . , ( ) ++ 17 FileSystem. , , , . , , .

, ++ (, , Boost) - , . , - , . , , .

, , std::mem_fn . ++, , path::string - . , , , , Boost.

, , :

std::transform(
    users.begin(), users.end(), std::back_inserter(usersStrs),
    [](const auto &pth) -> decltype(auto) {return pth.string();});

, std::mem_fn. decltype(auto) , .

+5

, Windows UTF-16, std::string. Boost path.hpp Windows API wstring .

#   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;
    }

    //  string_type is std::wstring, so there is no conversion
    const std::wstring&  wstring() const { return m_pathname; }

Linux API wstring

#   else   // BOOST_POSIX_API

//  string_type is std::string, so there is no conversion
    const std::string&  string() const { return m_pathname; }

    const std::wstring  wstring() const
    {
      std::wstring tmp;
      if (!m_pathname.empty())
        path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
          tmp);
      return tmp;
    }

.

+1

Source: https://habr.com/ru/post/1683626/


All Articles