【问题标题】:Default argument and empty list initialization默认参数和空列表初始化
【发布时间】:2018-08-15 09:49:29
【问题描述】:

考虑以下代码,它是一个简单的类,其构造函数采用默认值作为参数。

// 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 的示例,这两者会导致不同的结果?

【问题讨论】:

  • 为什么这么冗长?我是否错过了什么或者问题基本上是关于T t = {};T t = T(); 之间的区别?

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


【解决方案1】:

不,它们不相等。第二个变体依赖于 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;
};

【讨论】:

    猜你喜欢
    • 2017-11-19
    • 2015-02-25
    • 2014-05-06
    • 2016-05-07
    • 1970-01-01
    • 2014-12-26
    • 2015-07-10
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多