c++ - static_cast 的 GCC 问题
问题描述
概括
我有一个类,我添加了一个类型转换运算符以转换为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
编写这种类型转换的正确方法是什么?在 Google 上搜索为字符编码转换带来了很多成功,但这不是我的问题。我不明白为什么basic_string
尽管使用static_cast
.
完整示例
这是一个最小的例子。在我的 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*()
(或两个转换运算符)。
推荐阅读
- sql-server - 如何查看所有表格的大小
- bash - 从字符串 JQ 的一部分中删除双引号
- visual-studio-code - 如何让 Visual Studio Code 提示在新窗口中打开文件夹
- kendo-ui - 为什么单击提交时kendoForm会触发两次?
- python - 在 for 循环之后维护 3D 列表中的维度
- c# - 在本地动态 365 v8.2 中调试自定义工作流活动
- c++ - 朋友运算符<<在模板类中重载?
- sql - Power Query 基于 ID 列表筛选记录
- arrays - 想要将非字母字符传递给 C 中的数组但遇到分段错误
- cassandra - Cassandra 删除键空间,表不工作