Vous pouvez utiliser C++0x auto
ainsi que le mot-clé spécialisation des modèles sur par exemple une fonction nommée boost::make_array()
(similaire à make_pair()
). Pour le cas où N
est soit 1 soit 2 arguments, nous pouvons alors écrire variante A comme
namespace boost
{
/*! Construct Array from @p a. */
template <typename T>
boost::array<T,1> make_array(const T & a)
{
return boost::array<T,2> ({{ a }});
}
/*! Construct Array from @p a, @p b. */
template <typename T>
boost::array<T,2> make_array(const T & a, const T & b)
{
return boost::array<T,2> ({{ a, b }});
}
}
et variante B comme
namespace boost {
/*! Construct Array from @p a. */
template <typename T>
boost::array<T,1> make_array(const T & a)
{
boost::array<T,1> x;
x[0] = a;
return x;
}
/*! Construct Array from @p a, @p b. */
template <typename T>
boost::array<T,2> make_array(const T & a, const T & b)
{
boost::array<T,2> x;
x[0] = a;
x[1] = b;
return x;
}
}
GCC-4.6 avec -std=gnu++0x
y -O3
génère le exactement le même code binaire pour
auto x = boost::make_array(1,2);
en utilisant à la fois A y B comme il le fait pour
boost::array<int, 2> x = {{1,2}};
Pour types définis par l'utilisateur (UDT), cependant, la variante B donne lieu à un constructeur de copie supplémentaire qui ralentissent généralement les choses et sont donc à éviter.
Notez que boost::make_array
des erreurs lorsqu'il est appelé avec des littéraux de tableaux de caractères explicites, comme dans le cas suivant
auto x = boost::make_array("a","b");
Je pense que c'est une bonne chose car const char*
les littéraux peuvent être trompeuse dans leur utilisation.
Modèles variadiques disponible dans GCC depuis la version 4.5, peut être utilisé pour réduire le code passe-partout de la spécialisation des modèles pour chaque élément du modèle. N
en un définition du modèle unique de boost::make_array()
défini comme suit
/*! Construct Array from @p a, @p b. */
template <typename T, typename ... R>
boost::array<T,1+sizeof...(R)> make_array(T a, const R & ... b)
{
return boost::array<T,1+sizeof...(R)>({{ a, b... }});
}
Cela fonctionne à peu près comme prévu. Le premier argument détermine boost::array
argument de modèle T
et tous les autres arguments sont convertis en T
. Dans certains cas, cela peut être indésirable, mais je ne suis pas sûr de la manière dont il est possible de le spécifier en utilisant des modèles variadiques.
Peut-être boost::make_array()
devrait aller dans les bibliothèques de Boost ?
0 votes
Vos classes ne sont pas constructibles car tout est
private
.5 votes
(les mots-clés d'accès ont été laissés de côté pour des raisons de simplicité pédagogique)
9 votes
Ne serait-il pas plus facile d'utiliser
struct
à la place declass
pour des raisons de simplicité pédagogique ? Je trouve le code qui se compile plus facile à apprendre ;-)4 votes
Lorsque j'ai copié votre code dans mon compilateur, j'ai dû ajouter ce que vous aviez omis. Donc, pour des raisons de simplicité pédagogique, vous pourriez envisager de ne pas rendre la tâche difficile aux gens qui veulent vous aider à l'avenir.
1 votes
Steve/John : vrai sur les deux points. mea culpa.
0 votes
Corrigé (je pense... Je n'ai pas d'environnement de développement C++ rapide et facile sur ma machine)
1 votes
@Jason : Prends-en un, c'est inestimable. Vous pouvez aussi utiliser codepad.org pour un code similaire à celui-ci.