【问题标题】:Uniform Initialization to call a constructor other than initializer list统一初始化以调用初始化列表以外的构造函数
【发布时间】:2021-01-05 10:53:16
【问题描述】:

我最近遇到了 C++14 标准的统一初始化问题。我编写了一个代码,它声明了一个具有两个构造函数的类,第一个是参数化构造函数,另一个是具有intializer_list 的构造函数。代码如下,

#include <iostream>
#include <vector>

class MyClass final {
public:
    MyClass() = default;

    explicit MyClass(const int a, const int b)
        : m_a(a)
        , m_b(b)
    {
        std::cout << "From constructor" << std::endl;
    };

    MyClass(std::initializer_list<int> init_li)
        : m_a(init_li[0])
        , m_b(init_li[1])
    {
        std::cout << "Initializer List constructor" << std::endl;
    }

    void PrintValues() const
    {
        std::cout << m_a << " " << m_b << std::endl;
    }

private:
    int m_a, m_b;
}

int
main(void)
{
    using namespace std;

    vector<int> a{ 1, 2 }; // Creates a vector with initializer list. Very nice.
    vector<int> a{ (1, 2) }; // Calls a vector constructor "explicit vector(std::size_t __n, const std::allocator<int> &__a = std::vector<int>::allocator_type())" NOT INITIALIZER LIST constructor. Okay.

    MyClass a{ 1, 2 }; // Calls the initializer list constructor. Fine.
    MyClass b{ (1, 2) }; // Also calls the initializer list constructor. What???

    b.PrintValues();

    return 0;
}

所以,我的问题是为什么我不能像在带括号的向量中那样在 MyClass 中调用具有统一初始化的初始化列表以外的构造函数?

【问题讨论】:

    标签: c++ vector uniform-initialization


    【解决方案1】:

    这段代码:

    MyClass a2{ (1, 2) };
    

    无法调用 2 参数构造函数。发生的情况是,在表达式(1,2) 中,1 在逗号运算符之前被计算,它被丢弃,表达式的结果是2。这显然调用了initializer_list 构造函数。

    启用警告,例如-Wall 编译器会告诉你这个。


    请注意,vector&lt;int&gt; a{ (1, 2) }; 调用中也会发生同样的事情。 1 被丢弃,并调用带有单个参数的向量构造函数。

    【讨论】:

    • 对于vector&lt;int&gt; a { (1, 2) },1 不会被丢弃。它调用explicit vector(std::size_t __n, const std::allocator&lt;int&gt; &amp;__a = std::vector&lt;int&gt;::allocator_type()) 构造函数,创建一个大小为1 和第一个值a[0] = 2 的向量。我使用了 -Wall 标志,但没有收到任何警告。如果我有带有 1 个参数的构造函数,那仍然会调用初始化列表构造函数。请重新检查代码并具体说明...使用带有C++14 标准的TDM GCC 9.2.0。
    • 现在我明白了!这是逗号运算符的魔力,它计算最后一个元素,因为运算符与括号相关联。谢谢你的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多