我有一个包含数组的结构,我想将一个初始化器列表传递给struct的构造函数,以转发到数组.为了说明,我试过:
#include <initializer_list> struct Vector { float v[3]; Vector(std::initializer_list<float> values) : v{values} {} }; int main() { Vector v = {1,2,3}; }
error: cannot convert ‘std::initializer_list<float>’ to ‘float’ in initialization
I tried using parentheses instead of braces for v但是给出了错误:
error: incompatible types in assignment of ‘std::initializer_list<float>’ to ‘float [3]’
我尝试这样做的主要动机是避免以下警告:
template <int N> struct Vector { float v[N]; }; template <> struct Vector<2> { float x,y; }; int main() { Vector<2> v2 = {1.0f,2.0f}; // Yay,works Vector<3> v3 = {1.0f,2.0f,3.0f}; // Results in warning in clang++ Vector<3> u3 = {{1.0f,3.0f}}; // Must use two braces to avoid warning // If I could make Vector<N> take an initializer list in its constructor,I // could forward that on to the member array and avoid using the double braces }
warning: suggest braces around initialization of subobject
所以我的问题是:如何初始化一个初始化列表的成员数组? (即如何使第一个代码工作?还是不可能?
解决方法
如果你的课程是
aggregate,你可以使用你的语法
template < std::size_t len > struct Vector { float elems[len]; }; Vector<3> v = {1.0f,3.0f};
注意:这是可能的,由于大括号.不需要v = {{1,3}};虽然这也是可能的. Clang发出此警告,因为双括号更清晰,更容易出错的语法(一个用于初始化v和一个用于初始化子集合elems).
如果你的类不是聚合,你可以使用可变模板:
#include <array> #include <cstddef> template < std::size_t len > struct Vector { std::array < float,len > m; // also works with raw array `float m[len];` template < typename... TT > Vector(TT... pp) : m{{pp...}} {} // better,using perfect forwarding: // template < typename... TT > // Vector(TT&&... pp) : m{{std::forward<TT>(pp)...}} // {} }; Vector<3> a = {1.0f,3.0f};