classe template: ctor contre function -> nouvelle norme C ++

dans cette question:
modèle; Point ; Point
Dennis et Michael ont remarqué le constructeur déraisonnablement implémenté.
Ils avaient raison, je n’ai pas considéré cela à ce moment. Mais j’ai découvert qu’un constructeur n’aide pas beaucoup pour une classe de modèles comme celle-ci, une fonction est ici beaucoup plus pratique et sûre

namespace point { template  struct Point { TX[ dims ]; std::ssortingng str() { std::ssortingngstream s; s << "{"; for ( int i = 0; i < dims; ++i ) { s << " X" << i << ": " << X[ i ] << (( i < dims -1 )? " |": " "); } s << "}"; return s.str(); } Point toint() { Point ret; std::copy( X, X+dims, ret.X ); return ret; } }; template  Point Create( T X0, T X1 ) { Point ret; ret.X[ 0 ] = X0; ret.X[ 1 ] = X1; return ret; } template  Point Create( T X0, T X1, T X2 ) { Point ret; ret.X[ 0 ] = X0; ret.X[ 1 ] = X1; ret.X[ 2 ] = X2; return ret; } template  Point Create( T X0, T X1, T X2, T X3 ) { Point ret; ret.X[ 0 ] = X0; ret.X[ 1 ] = X1; ret.X[ 2 ] = X2; ret.X[ 3 ] = X3; return ret; } }; int main( void ) { using namespace point; Point p2d = point::Create( 12.3, 34.5 ); Point p3d = point::Create( 12.3, 34.5, 56.7 ); Point p4d = point::Create( 12.3, 34.5, 56.7, 78.9 ); //Point p1d = point::Create( 12.3, 34.5 ); //no suitable user defined conversion exists //Point p1i = p4d.toint(); //no suitable user defined conversion exists Point p2i = p2d.toint(); Point p3i = p3d.toint(); Point p4i = p4d.toint(); std::cout << p2d.str() << std::endl; std::cout << p3d.str() << std::endl; std::cout << p4d.str() << std::endl; std::cout << p2i.str() << std::endl; std::cout << p3i.str() << std::endl; std::cout << p4i.str() <> c; } 

La nouvelle norme C ++ a-t-elle de nouvelles améliorations, fonctionnalités de langage ou simplifications concernant cet aspect du ctor d’une classe de modèle?
que pensez-vous de la mise en œuvre de la combinaison d’espace de nom, de structure et de fonction Create?
Merci d’avance
Oops

Oui, comme Michael l’a souligné dans sa réponse à votre question précédente, en C ++ 0x, vous pourrez utiliser une liste d’initialiseurs pour transmettre un nombre arbitraire d’arguments à votre ctor. Dans votre cas, le code ressemblerait à quelque chose comme:

 template  class point { TX[dims]; public: point(std::initializer_list const &init) { std::copy(init.begin(), init.begin()+dims, X); } }; 

Vous pouvez créer un object point avec ceci quelque chose comme:

 point<3, double> x{0.0, 0.0, 0.0}; 

Personnellement, je ne suis cependant pas sûr d’aimer le design de base. En particulier, je préférerais que X devienne un std::vector et détermine le nombre de dimensions ssortingctement à partir de la liste de parameters passée au lieu de l’avoir comme argument de modèle:

 template  class point { std::vector X; public: point(std::initializer_list init) { std::copy(init.begin(), init.end(), std::back_inserter(X)); } }; 

Cela comporte toutefois certains compromis: les points avec un nombre différent de dimensions sont toujours du même type. Par exemple, il affirme qu’il est raisonnable d’atsortingbuer un point 2D à un point 3D ou inversement.

Comme le tableau est public, il est possible d’omettre le constructeur et d’autoriser l’initialisation de l’agrégat (comme boost::array par exemple).

 Point<2, int> p = {1, 2}; 

Ce n’est pas pire que d’avoir à appeler une fonction de création. (La fonction de création peut encore être utile comme utilitaire.)


En C ++ 0x, vous pourrez avoir toutes sortes de fraîcheur. Par exemple, jouez avec des templates variadiques, pour le faire vérifier à la compilation si le constructeur est appelé avec un nombre correct d’arguments. (Ce qui suit pourrait également vérifier si les arguments ...U sont tous du type T , avec encore plus de plaisir pour la métaprogrammation, mais cela n’est peut-être pas absolument nécessaire.)

 //helper to copy variable amount of arguments into an array namespace detail { template  void copy_variadic(T* p, U value) { *p = value; } template  void copy_variadic(T* p, First var, Rest ...args) { *p = var; copy_variadic(++p, args...); } } //detail template < unsigned int dims, typename T > struct Point { TX[ dims ]; Point() : X{} { } template  Point(U... args) { static_assert(sizeof...(args) == dims, "Too many or too few arguments to Point constructor"); detail::copy_variadic(X, args...); } //... }; 

(En fait, avec quelques modifications – transmission parfaite – copy_variadic ferait un ajout intéressant à ma collection d’utilitaires de modèles variadiques, si quelqu’un ne venait pas et ne copy_variadic pas un moyen nettement meilleur.)