Я создал шаблон класса.В зависимости от аргументов шаблона он поддерживает разные операции.Шаблон класса должен быть ( неявно ) создан для нескольких комбинаций аргументов шаблона.Для некоторых из этих комбинаций могут быть функции-члены, которые не имеют смысла (а также не компилируются).Однако до тех пор, пока я не применяю явное создание экземпляров, кажется, что все работает так, как нужно.
Теперь есть такие страшные случаи, которые называются "неопределенными", "неопределенными", "плохосформирован; диагностика не требуется ",….Я определенно хочу избежать любой из этих вещей.Поэтому я прошу совета, как справиться с этой ситуацией.
Вот пример, который показывает то же самое наблюдение.Обратите внимание, что меня не очень интересует, как исправить этот точный пример игрушки.
#include <iostream>
#include <type_traits>
template<class T>
struct SingleSink {
SingleSink(T) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
template<class T>
struct DoubleSink {
DoubleSink(T, T) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
template<class T, int arity /*, some other stuff */>
struct SuperSink {
// This class shall do something special depending on, say, `arity`.
// Instead of partially specializing the whole class template (and introducing
// code duplication for the remaining functionality), let us externalize the
// `arity`-dependent behavior to a special member.
using Sink = std::conditional_t<
arity == 1,
SingleSink<T>,
DoubleSink<T>
>;
Sink sink_;
// [some more data members that do not depend on `arity`]
// for a fixed `Sink` one of the following constructors should fail to compile
SuperSink(T i) : sink_{i} {}
SuperSink(T i, T j) : sink_{i, j} {}
// ... so these are what I call "conditionally invalid member functions".
};
// explicit instantiation yields error (deactivated by comments):
// template struct SuperSink<int, 1>;
// template struct SuperSink<int, 2>;
int main() {
// implicit instantiation works
SuperSink<int, 1>{5};
SuperSink<int, 2>{5, 6};
// these yield a compile error (as desired)
// SuperSink<int, 1>{5, 6};
// SuperSink<int, 2>{5};
}
- Являются ли эти условно недействительные функции-члены проблемой, если мне никогда не требуется явная реализация?
- Если да, то стоит ли проверять работоспособность явной реализации?