Как уже говорили другие, на how to distinguish between 2D and 3D?
отвечает простое использование dims
в качестве переменной.
Более интересный вопрос - как заставить конструкторы вести себя так, чтобы можно было вызывать только правильный,Один из вариантов - boost::enable_if
, который генерирует целенаправленную ошибку компилятора для существенной отмены объявления функции, если условие не выполняется.
template <int dims, typename T>
struct Point {
T X[dims];
Point(){} // should this really be empty?
Point( typename enable_if_c< dims == 2, T >::type X0, T X1 ) {
X[0] = X0;
X[1] = X1;
}
Point( typename enable_if_c< dims == 3, T >::type X0, T X1, T X2 ) {
X[0] = X0;
X[1] = X1;
X[2] = X2;
}
Этот метод обычно называется SFINAE, дляОшибка замещения не является ошибкой (подтекст: компилятор может попробовать другую перегрузку), но в этом случае мы действительно хотим ошибку.
Другой альтернативой является предоставление типа переменной и аргумента по умолчанию для выборочного отключениятретий аргумент, или принудительно укажите его:
template< int dims, typename T >
class tweak_point_ctor_argument; // disallow general case of dims != 2,3
template< typename T >
class tweak_point_ctor_argument< 2, T > {
tweak_point_ctor_argument() {} // private constructor
typedef tweak_point_ctor_argument type;
operator int() { return 0; }
friend struct Point;
};
template< typename T >
class tweak_point_ctor_argument< 3, T > {
typedef T type;
friend struct Point;
};
…
Point( T X0, T X1,
typename tweak_point_ctor_argument< dims, T >::type X2
= tweak_point_ctor_argument<dims, T>() ) {
X[0] = X0;
X[1] = X1;
X[2] = X2;
}
Если dims
равен 2, ::type
оценивается как tweak_point_ctor_argument< 2, T >
, что не может быть построено, кроме как по умолчанию в аргументе.Таким образом, пользователь не может вызвать конструктор с третьим параметром.Если dims
равен 3, ::type
оценивается как T
, в результате чего инициализатор аргумента по умолчанию становится недействительным, что вынуждает пользователя не использовать его.
Я не тестировал этот код, это простодемонстрация различных способов решения проблемы, enable_if
является предпочтительным методом здесь.