Учитывая класс с параметрами шаблона typename T
и class Tuple
Я хочу предоставить специальный конструктор, если Tuple
имеет std::vector
-подобные функции-члены reserve
и push_back
. Если Tuple
не имеет такие функций-членов, то я хочу, чтобы обеспечить специальный конструктор, если Tuple
конструктивен из переменных числа аргументов типов, конвертируемых в T
, т.е.Как я могу условно переключаться между двумя конструкторами с одинаковой сигнатурой?
template<typename T, class Tuple>
class vector
{
template<typename... Elements,
typename = decltype(std::declval<Tuple>().push_back(T())),
typename = decltype(std::declval<Tuple>().reserve(size_type()))>
vector(Elements&&... elements)
{ /* ... */ }
template<typename... Elements, typename = typename = decltype(Tuple{ static_cast<T>(std::declval<Elements>())... })>
vector(Elements&&... elements)
{ /* ... */ }
};
Вопрос 1: Очевидно, что в коде выше компилятора не знает, что я хочу, по возможности, взять первый конструктор. Как я могу добиться желаемого поведения?
Вопрос 2: Предполагая, что первый конструктор не существует, почему следующий код приведет к ошибке компилятора «не может преобразовать из списка инициализаторов в
vector<double, Tuple<double>>
»:
template<typename T>
class Tuple
{
public:
Tuple() { }
Tuple(std::initializer_list<T>) { }
};
int main()
{
vector<double, Tuple<double>> x = { 1, 2, 3 };
return 0;
}
Что происходит, когда оба условия ('A' и' B') не выполняются. Тогда 'ctor_tag' будет' no_tag'. Должен ли я предоставить третий конструктор для этого тега? – 0xbadf00d
@ 0xbadf00d зависит от того, является ли неудовлетворение логической ошибкой или нет. Невыполнение вопроса no_tag предоставило бы вам ошибку компилятора всякий раз, когда одно из предварительных условий (аргументы из реализованного типа) не выполняется. Это может быть очень полезно. –
@RichardHodges Идея состоит в том, чтобы условно включить эти конструкторы, если «Tuple» подходит. Если 'Tuple' не подходит, то эти конструкторы должны быть отключены. Ошибка компилятора не должна генерироваться, поскольку я не хочу принуждать 'Tuple' удовлетворять одному из двух условий. – 0xbadf00d