【问题标题】:Isn't using uniform initialization dangerous?使用统一初始化不危险吗?
【发布时间】:2014-05-04 11:58:41
【问题描述】:

几天前我发现了统一初始化,我到处都看到每个人都应该尽可能地使用它。

但是,我不禁认为这种新语法比它的价值更麻烦......


第一个例子

假设我编写了一个库,其中有一个这样的结构:

struct MyStruct
{
    int member0;
    int member1;
}

用户可以使用聚合初始化编写类似这样的内容:

MyStruct myVar = {0, 1}; // member0 = 0 and member1 = 1

现在,假设我更新了我的库,结构现在看起来像这样:

struct MyStruct
{
    int member0;
    int member1;

    MyStruct(int p0, int p1) : member0(p1), member1(p0){}
}

在 C++11 之前,用户代码会停止编译,这将迫使用户重写他的代码并使用构造函数。但是现在,代码将编译并被解释为统一初始化:

MyStruct myVar = {0, 1}; // member0 = 1 and member1 = 0

在用户不知情的情况下,更新他的库会使他的代码做一些非常不同的事情!


第二个例子

现在,假设我的库中有这样的课程:

class MyClass
{
public:
    MyClass(int size, int default = 0) : elements(size, default){}
private:
    std::vector<int> elements;
}

用户可以这样使用它:

MyClass myVar (3,1);  // 3 elements with value 1

或者,使用统一初始化,像这样:

MyClass myVar {3,1};  // 3 elements with value 1

再一次,让我们说我更新了我的图书馆。这个类现在看起来像这样:

class MyClass
{
public:
    MyClass(int size, int default = 0) : elements(size, default){}
    MyClass(std::initializer_list<int> elts) : elements(elts){}
private:
    std::vector<int> elements;
}

如果使用经典构造函数不会有问题:

MyClass myVar (3,1);  // 3 elements with value 1

但如果调用统一初始化,代码解释将会改变:

MyClass myVar {3,1};  // 2 elements with values 3 and 1

基于这些示例,在我看来,用户使用统一初始化是极其危险的,因为当将内容添加到使用的库时,代码解释可能会发生变化,根本没有任何警告。

更糟糕的是,统一初始化的引入使聚合初始化变得危险。

我错过了什么吗?是否存在使用统一初始化既安全又有用的情况?

【问题讨论】:

  • +1 很有趣的一点。对于第二种情况,两种情况的语法相似,但仍有区别。但是对于第一种情况,这看起来很麻烦。
  • 我认为无论是否涉及统一初始化,更改接口都是危险的。

标签: c++11 uniform-initialization list-initialization


【解决方案1】:

我认为您解决的两个问题与统一初始化本身关系不大,但说明了更改接口的危险。

您可以通过像这样更新您的库来归档用户代码中相同的次优更改:

struct MyStruct
{
    int member1;
    int member0;
}

不涉及统一初始化。在 c++11 之前,也可以更改重载决议选择的构造函数:

class some_class
{
    public:
    some_class(int);
}

用户编码:

some_class var(1.0);

如果代码改为:

class some_class
{
    public:
    some_class(int);
    some_class(double);
}

将调用第二个构造函数。同样,没有涉及统一初始化,但同样的问题发生了。

因此,虽然这两个示例都展示了用户代码的含义可以通过更改库接口来更改的事实,但这不是统一初始化引入或特定于统一初始化的问题,而是次优设计。它只是说明了应该非常仔细地设计库接口这一事实。

相反,统一初始化提供了一些真正的优势。对于那些,请参阅excellent answer

【讨论】:

  • 你说得有道理。但是我想这意味着纯粹主义者不会那么多使用统一初始化......
  • 纯粹主义者通常不使用任何东西,因为它很危险。他们不设计界面,因为他们可以改变,等等......
猜你喜欢
  • 2018-10-17
  • 1970-01-01
  • 2011-12-31
  • 2020-03-18
  • 2012-02-05
  • 2012-05-17
  • 2012-07-17
  • 2018-05-07
  • 1970-01-01
相关资源
最近更新 更多