static_cast:转换函数模板——它们真的有效吗
static_cast : Conversion function templates - are they really working?
就我阅读static_cast而言,以下代码应该可以工作:
#include <iostream>
#include <string>
class ConvSample
{
public:
template<typename T>
constexpr operator T(){
return {};
}
};
int main()
{
ConvSample aInst;
int i = aInst;
std::cout << i << "n";
std::string str = static_cast<std::string>(aInst);
std::cout << str << "n";
return 0;
}
它与Clang这样的编译器配合得很好。但例如,MSVC或ICC没有。
请参阅编译器资源管理器
通常,他们抱怨由于std::string提供的构造函数不能真正工作而导致的一些歧义。
此外,如果我在gcc上打开Wconversion,我会出现分段错误?!
代码中有什么错误吗?这些错误只是编译器错误吗?如果我将代码更改为不使用模板,则效果非常好:编译器资源管理器
不幸的是,这里的标准很模糊([expr.static.cast]/4,省略引用(:
如果存在从
e
到T
的隐式转换序列,或者如果从e
直接初始化对象或类型为T
的引用的重载解析将找到至少一个可行的函数,则表达式e
可以显式转换为类型T
。[…][T]从e
直接初始化结果对象。[…]
这两个启用条件在这里都成立:有一个隐式转换序列(由所需的转换函数调用组成(,并且有几个可行的函数用于直接初始化(因为std::string
构造函数的各种单个参数也有隐式转换序列(。
然而,只有隐式转换序列的复制初始化拒绝将ConvSample
转换为(比如(const char*
,然后再转换为std::string
,才提供了一种产生std::string
的明确的方法:它专门寻找到目标类型的转换函数,而允许转换为(比方(const std::string&
,常见的实现并不意味着转换函数模板也应该为该类型实例化,并且变得不明确。
最终调用的直接初始化在std::string
的5个单参数构造函数中是不明确的(类似std::string_view
的类型有6个(:ConvSample
当然可以以相同的"成本"转换为其中任何一个的参数类型。
接受这一点的编译器正在应用复制初始化规则(但仍允许explicit
转换(。那些拒绝它的人正在应用直接初始化,我认为这正是目前措辞所要求的。对隐式转换序列的引用仅在CWG242的C++17中引入,并且显然在该领域存在实现分歧。
- 欧拉项目#8答案是大以获得有效答案
- 调整大小后指向元素值的指针unordered_map有效?
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- GCC对可能有效的代码抛出init list生存期警告
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- 有效地使用std::unordered_map来插入或增加键的值
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 自定义先决条件对移动分配运算符有效吗
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- 为什么这种直接初始化有效?(C++17)
- 递归函数有效,但无法记忆
- 在C++中初始化向量映射的最有效方法
- 字节真的是最小可寻址单元吗
- static_cast:转换函数模板——它们真的有效吗
- delete[]在C++中真的有效吗
- 在C++中的函数调用内部执行强制转换时,强制转换是否真的有效
- 在64位x 64位乘法中使用Karatsuba算法真的有效吗