c++ - What's the correct way to initialize a member array with an initializer list? -
i have struct
holds array, , i'd pass initializer list struct's constructor forwarded on array. illustrate, tried:
#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>’ ‘float’ in initialization
i tried using parentheses instead of braces v
gave error:
error: incompatible types in assignment of ‘std::initializer_list<float>’ ‘float [3]’
my main motivation trying avoid following warning clang generates:
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, 2.0f, 3.0f}}; // must use 2 braces avoid warning // if make vector<n> take initializer list in constructor, // forward on member array , avoid using double braces }
warning: suggest braces around initialization of subobject
so question is: how can initialize member array initializer list? (i.e. how can make first code work? or not possible?
if class aggregate, can use syntax
template < std::size_t len > struct vector { float elems[len]; }; vector<3> v = {1.0f, 2.0f, 3.0f};
note: possible due brace-elision. no need v = {{1,2,3}};
though possible. clang issues warning because clearer , less error-prone syntax double braces (one initializing v
, 1 initializing sub-aggregate elems
).
if class not aggregate, can use variadic templates:
#include <array> #include <cstddef> template < std::size_t len > struct vector { std::array < float, len > m; // works 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> = {1.0f, 2.0f, 3.0f};
Comments
Post a Comment