J'ai un petit et joli petit métier qui répond à tous mes besoins jusqu'à maintenant.Résolution d'un constructeur C++ et d'une ambiguïté d'appel
template <typename T>
class Array
{
...
public:
int Data; // custom value
virtual void InitData() { Data = 0; }
Array(const Array& array);
template <typename U, typename = std::enable_if<std::is_same<U, T>::value, U>> Array(const Array<U>& array);
template <typename... Ts> Array(const Ts&... items);
void Add(const T& item);
template <typename... Ts> void Add(const T& item, const Ts&... rest);
void Add(const Array& array);
}
Le template <typename... Ts> Array(const Ts&... items);
me laisse faire Array<T> array = { ... }
, et d'attribuer et de retour {...}
listes de initialiseur. Parce qu'aucun des constructeurs n'est explicite, c'est incroyablement pratique, mais c'est aussi la raison pour laquelle je suis coincé maintenant.
J'aimerais pouvoir ajouter quelque chose de "raisonnable" aux tableaux. Mon principal cas d'utilisation est en ce moment:
using Curve = Array<float2>;
class Poly : public Array<float2> { using Array::Array; void InitData() override { Data = 1; } };
class Curve2 : public Array<float2> { using Array::Array; void InitData() override { Data = 2; } };
class Curve3 : public Array<float2> { using Array::Array; void InitData() override { Data = 3; } };
La substance std::is_same<>
est au-dessus spécifiquement pour être en mesure de traiter toutes les courbes que le même, mais pas les mêmes: les types de courbes de degré différent, et tout est bien « statiquement tapé ", donc tout ce que je fais dans une fonction comme DrawCurve(const Curve&)
est de vérifier le degré et ensuite prendre une mesure appropriée. Curve
est un alias sympa pour Array, et Curve2 etc. sont des spécialisations de degré. Cela fonctionne très bien. Quand j'entre dans la construction de courbe, j'ai habituellement un objet de courbe, auquel j'ajoute des points ou des segments de courbe. Donc, je voudrais pouvoir faire:
Curve3 curve;
curve.Add(float2()); // ambiguity
curve.Add(Array<float2>());
Malheureusement, je reçois une ambiguïté ici quand je l'appelle ajouter, parce que Add() prendra soit un float2
ou un Array<float2>
, qui fonctionne très bien, mais un tableau a le constructeur implicite template <typename... Ts> Array(const Ts&...)
, qui peut prendre float2
comme argument. Ainsi, l'ambiguïté est entre
Array::Add(float2()); // and
Array::Add(Array<float2>(float2()));
J'ai essayé de faire des constructeurs qui prennent des tableaux explicites, comme
template <typename A, typename = std::enable_if<std::is_same<A, Array>::value, A>>
void Add(const Array& array);
Mais j'obtenir de nouvelles erreurs de conversion de Curve3 à FLOAT2, etc., et il devient un gâchis. Mon espoir est que quelque part dans les profondeurs des modèles ou d'autres goodies C++ réside une solution simple qui est juste ce dont j'ai besoin. (Oui, je sais que je peux juste renommer les méthodes :: AddItem() et :: AddArray() et le problème sera terminé dans une seconde, mais je ne veux pas cela parce que finalement je veux doubler tout cela avec +=
puis la plupart du temps juste utiliser.
Toutes les idées?
juste branché le code dans [ici] (http://coliru.stacked-crooked.com/a/beaea40305a2119f), il ne semble pas y avoir une ambiguïté entre ces deux ajoute –