У меня есть приятный и маленький общий характер типа Array, который до сих пор подходит всем моим потребностям.Устранение конструктора C++ и неопределенность вызова
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);
}
template <typename... Ts> Array(const Ts&... items);
позволяет мне делать Array<T> array = { ... }
, и назначать и возвращать {...}
списки инициализатора. Поскольку ни один из конструкторов не является явным, это невероятно удобно, но также является причиной, по которой я сейчас застрял.
Я хотел бы иметь возможность добавлять что-либо «разумное» к массивам. Мой главный случай использования прямо сейчас:
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; } };
std::is_same<>
материала выше специально, чтобы иметь возможность рассматривать все кривые, как то же самое, но не то же самое: типы кривых разной степени, и все хорошо «статический напечатано ", поэтому все, что я делаю в функции вроде DrawCurve(const Curve&)
, - это проверить степень, а затем предпринять соответствующие действия. Curve
- хороший псевдоним для Array, Curve2 и т. Д. - это специализации по степени специализации. Он работает очень хорошо.
Когда я вхожу в конструкцию кривой, у меня обычно есть объект кривой, к которому я добавляю либо точки, либо сегменты кривой. Так что я хотел бы быть в состоянии сделать:
Curve3 curve;
curve.Add(float2()); // ambiguity
curve.Add(Array<float2>());
К сожалению, я получаю неоднозначность здесь, когда я называю добавить, потому что Add() будет принимать либо float2
или Array<float2>
, который прекрасно работает, но массив имеет неявный конструктор template <typename... Ts> Array(const Ts&...)
, который может принимать float2
в качестве аргумента. Таким образом, неоднозначность между
Array::Add(float2()); // and
Array::Add(Array<float2>(float2()));
Я попытался сделать конструктор, которые принимают массивы явно, как
template <typename A, typename = std::enable_if<std::is_same<A, Array>::value, A>>
void Add(const Array& array);
Но тогда я получаю новые ошибки преобразования из Curve3 в float2 и т.д., и это становится беспорядком.
Моя надежда заключается в том, что где-то в глубине шаблонов или других положительных героев C++ лежит простое решение, которое именно то, что мне нужно. (Да, я знаю, что могу просто переименовать методы :: AddItem() и :: AddArray(), и проблема закончится через секунду, но я не хочу этого, потому что в конце концов я хочу удвоить все это с помощью +=
а затем в основном просто использовать.
Любые идеи?
только что подключил код в [здесь] (http://coliru.stacked-crooked.com/a/beaea40305a2119f), похоже, что между этими двумя добавочными номерами не существует двусмысленности. –