constructeur à N arguments, N étant un paramêtre template
Je développe actuellement une bibliothèque de géométrie ND (2D, 3D et 4D, principalement), dont voici un extrait.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| using dimension_type = std::size_t;
// constexpr compatible mathematical N-dimensional vector
template <typename Value, dimension_type Dimensions>
class vector {
static_assert(Dimensions > 0, "No support for 0D (or less) vectors");
public:
using value_type = Value;
value_type values[Dimensions];
//agregate initialization
constexpr value_type const& operator[](dimension_type i) const { return values[i]; }
value_type& operator[](dimension_type i) { return values[i]; }
vector& operator += (vector const& other) { for (dimension_type i = 0; i < Dimensions; ++i) (*this)[i] += other[i]; return *this; }
constexpr vector add(vector const& other) const { return add(other, make_index_sequence()); }
private:
using make_index_sequence = std::make_integer_sequence<dimension_type, Dimensions>;
template<dimension_type... i>
using index_sequence = std::integer_sequence<dimension_type, i...>;
template<dimension_type... i>
constexpr vector add(vector const& other, index_sequence<i...>) const { return vector{ ((*this)[i] + other[i])... }; }
};
template <typename Value, dimension_type dimensions>
constexpr inline vector<Value, dimensions> operator + (vector<Value, dimensions> const& a, vector<Value, dimensions> const& b) { return a.add(b); } |
J'ai beau chercher, je ne vois pas comment écrire mes constructeurs, avec les contraintes suivantes:
- Ils doivent être constexpr c'est "vital"
- vector<double, 2> v; doit compiler et être {0, 0} (pas comme std::array)
- vector<double, 3> k{0,0,1}; doit être possible
- vector<double, 3> v{0, 1}; ne doit pas compiler, car il manque une composante. (pas comme std::array)
- f(vector<double, 3>); f({0, 1, 2}); doit compiler, sans avoir à préciser le type (f(vector<double, 3>{0,1,2})
Précisément, je ne sais pas comment écrire mon constructeur à N paramètres.
J'ai essayé avec l'"aggregate initialization", mais je n'ai pas le point 4
J'ai essayé avec un constructeur template variadique, mais le point 5 saute.
Code:
1 2 3 4
| template <typename T...>
constexpr vector(T... args): values{args...} {
static_assert(plein de choses);
} |
J'essaye avec std::initializer_list, mais le point 4 compile (j'ai seulement une exception).
Avez-vous une idée?