阅读以下博客后:
http://xania.org/200711/ambiguous-overloading
我开始问自己“我不应该总是明确地定义我的构造函数吗?”
所以我开始阅读的不仅仅是发现这篇文章:
http://www.sjbrown.co.uk/2004/05/01/always-use-explicit/
这显示了另一个例子,也解释了他背后的想法。 但当然这是一位博主的想法。
我很高兴收到你们中的一些人的意见,你们对这种态度的看法,你们对这个主题的体验以及对这两种方式的一些例子都会很好。
答案 0 :(得分:54)
传统观点认为构造函数采用一个参数(通过使用默认参数明确或有效地)应标记为explicit
,除非它们确实定义了转换({{1}可以从std::string
转换为后者的一个例子。你自己已经找到了原因,因为隐含的转换确实会使生活变得更加艰难。
可能明显的例外是复制构造函数。或许另一种方法是考虑大多数类型都可以从自身转换为自身,并且因此复制构造函数大部分时间都没有标记为const char*
。
虽然看起来标记所有其他类型的构造函数explicit
并没有伤害,但我反对它。因为虽然explicit
对在C ++ 03中采用多个参数的构造函数没有影响,但它在C ++ 11中确实有效。把它放入代码:
explicit
我个人发现,在一个返回struct foo {
explicit foo(int i);
foo(int i, int j);
explicit foo(int i, int j, int k);
};
foo make_foo()
{
/* Not C++11-specific: */
// Error: no conversion from int to foo
return 42;
// Okay: construction, not conversion
return foo(42);
// Okay: constructions
return foo(42, 42);
return foo(42, 42, 42);
/* C++11 specific: */
// Error: no conversion from int to foo
return { 42 };
// Not an error, not a conversion
return { 42, 42 };
// Error! Constructor is explicit
return { 42, 42, 42 };
// Not an error, direct-initialization syntax
return foo { 42, 42, 42 };
}
的函数中,我必须明确地返回foo
。我没有看到foo { 42, 42, 42 }
正在保护我。我真的希望explicit
语法的意思是“从给定的初始化器构造对象”,而{ initializers... }
会让我从中拯救我。 (由于explicit
在复制初始化的情况下可以归结为{ i }
- 大部分时间 - 我很乐意将其提升。)
所以我要说养成使用i
用于一元构造函数的习惯,和仅用于。