调用构造函数时必须有多明确
How explicit must you be when calling a constructor?
我有这个类
struct foo
{
explicit foo(const std::uint32_t& x, const std::uint32_t& y);
};
以及方法
int main()
{
std::int32_t x = -1;
std::int32_t y = -1;
foo f(x, y);
}
在我的编译器(MSVC2012)上,它编译并运行时将值x
和y
包装为无符号类型。我没想到会出现这种情况,但由于类型不匹配,我预计会出现编译错误。
我错过了什么?
如果运气不好,标准确实允许通过为常量引用传递的参数创建匿名临时参数来隐式转换已签名到未签名。
(请注意,对于非常量引用,这是不正确的)。
如果您使用的是C++11,最好的方法是使用删除构造函数
foo(const std::int32_t& x, const std::int32_t& y) = delete;
在C++11之前,你可以让这个构造函数private
,而不是定义。就像老式的不可复制的习惯用法一样。
MSVC2012是一种中途之家C++03/C++11编译器。它实现了一些C++11特性,但没有实现其他特性。不幸的是,构造函数的删除是不支持的功能之一,因此private
方法是可用的最佳方法。
实际上,您应该使用新的大括号初始化语法foo f{x, y}
,它至少会发出警告。之后,您可以将编译器配置为将警告视为错误并进行相应处理,因为好的代码通常也应该消除警告(因为如果希望进行转换,则应该使用显式强制转换)。
explicit
不会阻止使用构造函数参数的隐式转换(在绑定引用时会明显发生这种转换);它防止了隐式构造。
void bar(foo);
int main()
{
foo f({0, 0}); // doesn't matter that the arguments are implicitly converted
bar({0, 0}); // error - implicit conversion required here to pass a foo
bar(f); // crucially, ok because argument requires no conv. construction
}
相关文章:
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 减少复制构造函数调用
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 在 Google 测试中,我可以从构造函数调用 GetParam() 吗?
- C++ - 从另一个类构造函数调用类构造函数
- 在C++中初始化带有和不使用构造函数调用的对象有什么区别
- 是否可以从移动构造函数调用默认构造函数?
- 在模板生成器模式中分解重复的构造函数调用
- std::atexit 从全局对象的构造函数调用时的排序
- 对构造函数调用的约束
- 编译器错过了无效的构造函数调用,并调用不存在的(或私有的)默认构造函数
- 用构造函数调用填充向量
- 创建指针时是否没有构造函数调用
- 使用 emplace_back 避免移动构造函数调用的最佳方法?
- C++ 抽象类构造函数调用
- 为什么函数参数将带有参数的构造函数调用
- 为什么比“构造函数”调用更多的“解构器”调用
- 将对象传递给函数并不是导致构造函数调用