Je développe actuellement une bibliothèque de géométrie ND (2D, 3D et 4D, principalement), dont voici un extrait.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:
  1. Ils doivent être constexpr c'est "vital"
  2. vector<double, 2> v; doit compiler et être {0, 0} (pas comme std::array)
  3. vector<double, 3> k{0,0,1}; doit être possible
  4. vector<double, 3> v{0, 1}; ne doit pas compiler, car il manque une composante. (pas comme std::array)
  5. 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 : Sélectionner tout - Visualiser dans une fenêtre à part
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?