我正在尝试不使用STL初始化类的私有成员数组(因为我正在使用的Arduino微控制器平台不支持该数组)。这意味着没有std::array
或std::initializer_list
等。
以下代码可使用gcc 5.4.0和avr-gcc 4.9.2正确编译,但使用that seems to be a bug。 Clang抛出一个错误,说error: array initializer must be an initializer list
(按预期)。
代码
#include <iostream>
#define PRINTFN() std::cout << __PRETTY_FUNCTION__ << std::endl
class Object {
public:
Object(int number) : number(number) { PRINTFN(); }
Object(const Object &o) : number(o.number) { PRINTFN(); }
void print() { std::cout << "The number is " << number << std::endl; }
private:
const int number;
};
template <size_t N>
class ManyObjects {
public:
ManyObjects(const Object(&objects)[N]) : objects(objects) {}
void print() {
for (Object &object : objects)
object.print();
}
private:
Object objects[N];
};
int main() {
ManyObjects<3> many = {{1, 2, 3}};
many.print();
}
输出
Object::Object(int)
Object::Object(int)
Object::Object(int)
Object::Object(const Object&)
Object::Object(const Object&)
Object::Object(const Object&)
The number is 1
The number is 2
The number is 3
初始化objects
的正确方法是什么?还是在给定的约束下不可能?
答案 0 :(得分:1)
您可以使用可变参数模板:
在ManyObjects
类中:
template <typename... _Args>
ManyObjects(_Args&&... arguments) :
objects { arguments... }
{
}
更多here
答案 1 :(得分:0)
是的,可变参数模板可以工作,但是有点棘手:
template <size_t N>
class ManyObjects {
public:
template<typename T, typename ...Args>
ManyObjects(const T& x, Args&&... args) : objects{x, args...}{}
private:
Object objects[N];
};
int main() {
ManyObjects<3> many{1, 2, 3};
ManyObjects<3> copymany{many};
copymany.print();
}
对于任何固定的N,它可以解释为:
template <size_t N=3>
class ManyObjects {
public:
ManyObjects(int x, int y, int z) : objects{x, y, z}{}
...
};
这里发生了什么:
Object(int)
的定义,无法默认初始化对象。Object arr[N]
。要防止与副本构造函数匹配,可以在参数包之外指定第一个参数。您可以松开大小为0的结构,可以通过模板专门化来启用它。
ManyObjects<0> noneof;
noneof.print();
答案 2 :(得分:0)
我最终遵循了VTT的建议,并创建了自己的数组包装器。
如果有需要注意的事情或可能的错误等,我希望听到一些反馈。
#include <iostream>
class Object {
public:
Object(int number) : number{number} {}
void print() { std::cout << "The number is " << number << std::endl; }
private:
const int number;
};
// -------------------------------------------------------------------------- //
template <class T, size_t N> class ArrayWrapper {
public:
T &operator[](size_t index) { return data[index]; }
const T &operator[](size_t index) const { return data[index]; }
T *begin() { return &data[0]; }
const T *begin() const { return &data[0]; }
T *end() { return &data[N]; }
const T *end() const { return &data[N]; }
T data[N];
};
// -------------------------------------------------------------------------- //
template <size_t N> class ManyObjects {
public:
ManyObjects(const ArrayWrapper<Object, N> &objects, const char *name)
: objects{objects}, name{name} {}
void print() {
std::cout << name << std::endl;
for (auto &object : objects)
object.print();
}
private:
ArrayWrapper<Object, N> objects;
const char *name;
};
// -------------------------------------------------------------------------- //
int main() {
ManyObjects<3> many = {{1, 2, 3}, "Many"};
many.print();
}