默认参数和空列表初始化

时间:2018-08-15 09:49:30

标签: c++ c++11 default-constructor default-arguments list-initialization

考虑以下代码,该代码是一个简单类的构造函数,该构造函数带有一个带有默认值的参数。

// Version 1
template <class T>
struct object1 {
    using type = T;
    constexpr object1(const type& val = type()): value(val) {}
    type value;
};

// Version 2
template <class T>
struct object2 {
    using type = T;
    constexpr object2(const type& val = {}): value(val) {}
    type value;
};

// Main
int main(int argc, char* argv[]) {
    using type = /* Something */;
    object1<type> x1;
    object2<type> x2;
    auto value1 = x1.value;
    auto value2 = x2.value;
    // Is there certain types for which value1 and value2 will be different?
    return 0;
}

构造函数的两个版本是否等效(对于任何T总是会产生相同的结果),或者它们是不同的?

如果它们不同,是否可以提供一个T的示例,两者将导致不同的结果?

1 个答案:

答案 0 :(得分:6)

不,它们不是等效的。第二种变体依赖于T的默认构造函数的隐含性:

class foo
{
   public: explicit foo() {}
};

object1<foo> of{}; // ok
object2<foo> of{}; // error

我还认为从临时调用副本构造函数而不是在没有临时函数的情况下调用默认构造函数不是一个好主意。那最好是实现单独的构造函数:

template <class T>
struct object1 {
    using type = T;
    constexpr object1(void): value{} {}

    constexpr object1(const type& val): value{val} {}

    type value;
};