如何制作一个构造函数,让我可以使用花括号初始化列表进行构造?

问题描述 投票:0回答:3

我的 Phenotype 类具有以下构造函数:

Phenotype(uint8 init[NUM_ITEMS]);

我可以创建这样的表型:

uint8 data[] = {0,0,0,0,0};
Phenotype p(data);

但是当我尝试创建这样的一个时出现错误:

Phenotype p = {0,0,0,0,0};

输出:

$ make
g++ -Wall -g main.cpp -std=c++0x
main.cpp: In function ‘int main(int, char**)’:
main.cpp:109: error: no matching function for call to ‘Phenotype::Phenotype(<brace-enclosed initializer list>)’
main.cpp:37: note: candidates are: Phenotype::Phenotype(uint8*)

该错误似乎表明有一种方法可以定义一个采用大括号括起来的初始值设定项列表的构造函数。有谁知道如何做到这一点?

c++ c++11 initializer-list
3个回答
76
投票

它只能用于聚合(数组和某些类。与流行的看法相反,这也适用于许多非 Pod)。编写接受它们的构造函数是不可能的。

既然您将其标记为“C++0x”,那么这是可能的。神奇的词是“初始化列表构造函数”。这就像

Phenotype(std::initializer_list<uint8> c) {
  assert(c.size() <= std::size(m_array));
  std::copy(c.begin(), c.end(), m_array);
}

// used like
Phenotype p1{1, 2, 3};
Phenotype p2({1, 3, 2}); // works too
Phenotype p3(1, 2, 3); // doesn't work

但是,这样的初始化会默认构造数组,然后使用赋值运算符。如果您的目标是速度和安全(您会因太多初始化程序而出现编译时错误!),您还可以使用带有可变参数模板的普通构造函数。

这可能比需要的更通用(通常一个初始化列表就完全足够了,特别是对于普通整数)。它受益于完美转发,因此可以将右值参数移动构造到数组元素中

template<typename ...T>
Phenotype(T&&...t):m_array{ std::forward<T>(t)... } {

}

// used like
Phenotype p1{1, 2, 3}; 
Phenotype p2(1, 2, 3); // works too
Phenotype p3({1, 2, 3}); // doesn't work   

这是一个艰难的选择!

编辑更正,最后一个也可以,因为我们没有创建构造函数

explicit
,所以它可以使用
Phenotype
的复制构造函数,构造一个临时的
Phenotype
对象并将其复制到
p3 
。但这并不是我们真正希望的调用方式:)


7
投票

在 C++0x 中,您似乎可以为此创建一个构造函数。我自己没有这方面的经验,但看起来它叫做 initializer list-constructor.

容器可能会实现如下所示的初始化列表构造函数:

template<class E> class vector {
public:
    vector (std::initializer_list<E> s) // initializer-list constructor
    {
        reserve(s.size());  // get the right amount of space
        uninitialized_copy(s.begin(), s.end(), elem);   // initialize elements (in elem[0:s.size()))
        sz = s.size();  // set vector size
    }

    // ... as before ...
};

6
投票

您需要使用 std::initializer_list 模板类型。示例:

#include <iostream>
class X {
    public:
        X (std::initializer_list<int> list) {
        for (auto i = list.begin(); i != list.end(); i++) {
                std::cout << *i << std::endl;
            }
        }
};


int main () {
    X x = {1,2,3,4,5};
}
© www.soinside.com 2019 - 2024. All rights reserved.