c++ - static_cast<std::u16string> 的 GCC 问题

标签 c++ gcc visual-c++

总结

我有一个类,我向其中添加了类型转换运算符以转换为 std::u16string。该操作符的签名如下所示:

operator const std::u16string() const;

在我的 .cpp 文件中,我尝试将类类型的对象转换为 std::u16string,如下所示:

std::u16string sUTF16Password = static_cast<std::u16string>(Password_);

在 Visual Studio 2017 上,这工作得很好。但是,我的 Raspberry Pi 上的 GCC 6.3 在编译时出现以下错误:

error :  call of overloaded 'basic_string(MyClass&)' is ambiguous

写这个类型转换的正确方法是什么?在谷歌上搜索带来了很多字符编码转换的命中,但这不是我这里的问题。我不明白为什么尽管使用了 static_cast,但这里仍调用了 basic_string 构造函数。

完整示例

这是一个最小的例子。在我的 Raspberry Pi 上使用 g++ main.cpp 编译失败。

#include <iostream>
#include <string>

class MyClass
{
    private:
        std::u16string Str;
    public:
        MyClass() { Str = u"abcd"; }
        operator const char16_t*() const { return Str.c_str(); }
        operator std::u16string() const { return Str; }
};

int main()
{
    MyClass Tester;
    std::u16string TestStr = static_cast<std::u16string>(Tester);
    for (size_t idx = 0; idx < TestStr.size(); idx++)
        std::cout << idx << ": " << TestStr[idx] << std::endl;
    return 0;
}

gcc --version 的输出是 gcc (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516

g++ main.cpp 的完整输出是:

main.cpp: In function ‘int main()’:
main.cpp:17:61: error: call of overloaded ‘basic_string(MyClass&)’ is ambiguous
  std::u16string TestStr = static_cast<std::u16string>(Tester);
                                                             ^
In file included from /usr/include/c++/6/string:52:0,
                 from /usr/include/c++/6/bits/locale_classes.h:40,
                 from /usr/include/c++/6/bits/ios_base.h:41,
                 from /usr/include/c++/6/ios:42,
                 from /usr/include/c++/6/ostream:38,
                 from /usr/include/c++/6/iostream:39,
                 from main.cpp:1:
/usr/include/c++/6/bits/basic_string.h:476:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_
CharT, _Traits, _Alloc>&&) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
       basic_string(basic_string&& __str) noexcept
       ^~~~~~~~~~~~
/usr/include/c++/6/bits/basic_string.h:454:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&
) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
       ^~~~~~~~~~~~
/usr/include/c++/6/bits/basic_string.h:397:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::__cxx11::basic_st
ring<_CharT, _Traits, _Alloc>&) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
       basic_string(const basic_string& __str)
       ^~~~~~~~~~~~

如果我删除对 const char16_t* 的类型转换,这个例子编译得很好。我仍然不明白为什么同时进行两种类型转换是个问题。

最佳答案

如果您编译为 C++14(或更早版本),您将得到这个模棱两可的调用,因为 std::u16string(char16_t*) 参与了重载决议(通过 MyClass::operator const char16_t*()) 以及 MyClass::operator std::u16string()出现是更好的匹配。

这可以通过多种方式克服:

  • 使用 GCC 7 或更高版本编译为 C++17(或更高版本)(遗憾的是,这对 GCC 6 没有帮助)。
  • 删除 operator const char16_t*()
  • explicit 添加到 operator const char16_t*()(或两个转换运算符)。

关于c++ - static_cast<std::u16string> 的 GCC 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52851027/

相关文章:

c++ - WriteFile 将文件名写入文件

gcc - 为什么gcc在/usr/include/x86_64-linux-gnu中搜索在/usr/include之前

c++ - 错误消息无法打开包含文件 : 'gxall.h' : No such file or directory

C++ MFC 应用程序在 Windows 7 上运行缓慢,但在 XP 上运行迅速

c++ - 如果找到给定的单词,则保存下一个单词 (C++)

c++ - 从文件中读取值并使用类

c++ - 申请失败(make Killed)

c - GCC 内联汇编作为二进制数组

创建一个可以根据参数省略一行的宏

c++ - 我可以在没有 Visual Studio 的情况下使用 Visual C++ 编译器吗?