In my Point header I have:
15 template<typename real> class Point
16 {
17 public:
18 // Constructors
19 Point();
20 Point(const std::initializer_list<real>&);
21 Point(const std::initializer_list<real>&, const types::unitTypes);
22 Point(const real, const real, const real);
23 Point(const real, const real, const real, const types::unitTypes);
...
43 private:
44 std::array<real, 3> xyz_;
45 types::unitTypes units_;
46 };
Note that lines 20 and 44 show that the Point to should be able to be initialized with an initializer_list and I have private variable std::array<real, 3> xyz_. Now, I would like for my constructor of this to be something like the following:
31 template<typename T>
32 Point<T>::Point(const std::initializer_list<T>& xyz)
33 : xyz_(xyz)
34 , units_(types::au)
35 {};
However, it doesn't seem like I'm able to construct the array from an initializer and if I try to move that modify that from :xyz_(xyz) to something like
31 template<typename T>
32 Point<T>::Point(std::initializer_list<T> xyz)
33 : units_(types::au)
34 {
35 xyz_ = xyz;
36 };
it is not able to overload = for operands array and initializer. Is there a better way to go about this that I can use invoke Point<real>({x, y, z}); and initialize the xyz_ array internally?
Update:
I had tried to define Point(const std::array<real, 3>&) before but I get the following compilation error (essential parts extracted):
error: call of overloaded ‘Point(<brace-enclosed initializer list>)’ is ambiguous
...
note: candidate: ‘aided::point::Point<real>::Point(const std::array<real, 3>&) [with real = float]’
...
note: candidate: ‘constexpr aided::point::Point<float>::Point(const aided::point::Point<float>&)’
...
note: candidate: ‘constexpr aided::point::Point<float>::Point(aided::point::Point<float>&&)’
The first is candidate is the one I am intending to use. Are the second two somehow copy constructors that are able to be invoked via an initialization with an initializer list?
std::initializer_listandstd::arraydon’t cooperate as well as one would hope. Separate constructor arguments can give you a bit more flexibility, automatic template argument deduction and (also, to some extent) automatic choice of a type that can hold all the values:Now let’s test that↑ a bit and let’s not insist on
Realtoo strongly:This↑ seems to work and may generate the following output (modulo compilers’ RTTI naming differences):
Solving some of the caveats outlined in comments using deep(er) template decomposition and specialization would be a nice exercise, but may not be worth the hassle.