41

阅读以下博客后:

http://xania.org/200711/ambiguous-overloading

我开始问自己“我不应该总是明确定义我的构造函数吗?”

所以我开始阅读比发现这篇文章更多的内容:

http://www.sjbrown.co.uk/2004/05/01/always-use-explicit/

这显示了另一个例子,也解释了他背后的想法。但当然,这是一位博主的想法。

我很高兴听到你们中的一些人的意见,你对这种方式的看法,你对这个主题的经验以及任何一种方式的一些例子都会很好。

4

1 回答 1

63

传统观点认为,采用一个参数(通过使用默认参数显式或有效地)的构造函数应该被标记explicit,除非它们确实定义了转换(std::string可以从const char*后者的一个示例转换)。您自己已经弄清楚了原因,因为隐式转换确实会使生活变得比必须的更难。

一个可能明显的例外是复制构造函数。或者也许另一种方式是考虑大多数类型可以相互转换,因此复制构造函数explicit大部分时间都没有标记。

虽然看起来标记所有其他类型的构造函数explicit并没有什么坏处,但我反对它。因为虽然explicit在 C++03 中对采用多个参数的构造函数没有影响,但它在 C++11 中确实有效。将其放入代码中:

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在复制初始化的背景下——大多数时候——我很乐意放弃那个。)

所以我想说养成使用explicit一元构造函数的习惯,而且那些只有.

于 2012-09-15T12:38:26.093 回答