为什么 'explicit' 关键字允许隐式转化?
Why is the 'explicit' keyword allowing implicit conversions?
class Test {
private:
int value;
public:
void display(void)
{
cout << "Value [" << value << "]" << endl;
}
explicit Test(int i)
{
value=i;
}
};
int main() {
Test a(5);
Test b(4.9);
a.display();
b.display();
cin.get();
return 0;
}
浮点值被转换为 int,即使提到了显式。
我期望(错误地(浮点数不会转换为整数并且对象 b 不会被构造。
explicit
指的是构造函数本身,而不是构造函数的参数。 显式构造函数不能用作类型Test
的隐式转换。
void function( Test param );
function( 5 ); // Your "explicit" makes this call an error.
// The parameter must be explicitly cast, such as Test(5)
在 C++11 或更高版本中,可以使用模板参数的= delete
语法来阻止隐式参数转换。
Test(int i)
{
value=i;
}
template<typename T>
Test(const T&) = delete;
// ^ Aside from your int constructor and the implicitly-generated
// copy and move constructors, this will be a better match for any other type
在 C++20 或更高版本中,可以使用 std::same_as
概念阻止隐式参数转换。
Test(std::same_as<int> auto i)
{
value=i;
}
explicit
只是阻止任何隐式转换。因此,如果您有:
void foo(Test t);
不能调用foo(4);
,因为Test
构造函数是 explicit
。你必须打电话给foo(Test(4));
.explicit
关键字与施工期间可能必须发生的任何转换无关。
从标准 [class.conv.ctor]:
显式构造函数像非显式构造函数一样构造对象,但仅在 直接初始化语法 (8.5( 或显式使用强制转换(5.2.9、5.4(的位置。
这意味着Test t = 4;
也是非法的,但Test t(42.0)
很好。
这是一个
浮动积分转换.
也就是说:它是类型double
的prvalue到类型signed int
的prvalue之间的隐式转换。它丢弃小数部分。
TL;DR:转换发生在"double"和"int"之间,而不是在你的Test
构造函数中。如果要防止使用 float
或 double
调用该构造函数,可以添加定义:
Test(double) = delete;
在你的Test
课上。 在编译器资源管理器上直播
相关文章:
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 复制列表初始化的隐式转换的等级是多少
- 生成文件不对文件使用隐式规则
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 返回值优化:显式移动还是隐式
- 隐式常量/非常量运算符布尔
- 逐位操作的隐式类型转换
- 返回时不允许隐式转换
- 尝试使用算术运算符阻止隐式转换
- 获取隐式转换溢出从无符号到已签名的警告
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 我是否需要包含隐式使用/与 WindowsAPI 通信"Windows.h"?
- C++ G++ 编译器 - 错误:隐式声明的定义
- 隐式声明的 boost::iostreams::mapped_file_source 已被弃用
- 启用从"vector<const T>&"到"const vector&"的隐式转换<T>
- 隐式移动与复制操作和遏制
- C ++中无符号位长度类型之间的隐式转换,即uint8_t,uint16_t
- 统一初始化是隐式发生的,即使 int 强制转换运算符是使用 explicit 关键字声明的.原因是什么?
- 为什么 'explicit' 关键字允许隐式转化?