调用带有大括号封装的initilizer列表的类的构造函数

时间:2018-03-13 16:27:40

标签: c++

我如何定义一个构造函数,以便我可以像A({a,b,c})一样构造一个类A. 这是出于避免使用看似危险的可变构造函数的冲动。

代码:

#include <vector>

class A{
public:
A(const unsigned int a, const unsigned int b, const unsigned int c) /*: A({a,b,c})*/ {} 
A(const std::vector<unsigned int> v) {}
};


int main(){
A(1,2,3); //works
A({1,2,3}); // doesnt compile

return 0;
}

我的目标是构建一个具有任意多个隐藏层的网络。该向量应该包含相应层包含的节点数量。

编辑:

/home/simbla/qt_projects/minimalWorkingExample/main.cpp:158: error: call of overloaded 'A(<brace-enclosed initializer list>)' is ambiguous
 A({1,2,3});
          ^

解决方案:

使用std :: initializer_list而不是std :: vector

3 个答案:

答案 0 :(得分:2)

你问题中的构造函数实际上比你让它更多。这是你的编译器提供的另外两个:

A(A const&) = default;
A(A &&) = default;

现在有趣的是当你编写另一个初始化器A{1, 2, 3}时会发生什么。这称为您的第一个用户定义的c&#tor。没有什么新奇的。但是当您编写A({1, 2, 3})时,重载决策有两个选项。构建临时A{1, 2, 3}并复制它。或者为其他用户提供c&#39; tor。

在这两种情况下,它都是用户定义的转换序列。两者都不比另一个好,所以由于含糊不清,你会得到一个漂亮的闪烁错误。

解决方案?使用大括号初始化A{{1,2,3}};或提供initializer_list构造函数,以更好地匹配初始化列表参数。

答案 1 :(得分:1)

A(const std::vector<unsigned int> v) {}

不,矢量不是正确的。你想要

A(const std::initializer_list<unsigned int> v) {}

答案 2 :(得分:1)

我认为您正在寻找std::initializer_list

struct S {
    std::vector<int> v;
    S(std::initializer_list<int> l) : v(l) {
        std::cout << "constructed with a " << l.size() << "-element list\n";
    }
};

int main() {
    S s({1, 2, 3, 4, 5});

}