Я уже некоторое время пытаюсь работать с шаблонами, и чем больше я делаю, тем меньше понимаю, что понимаю. Эта последняя проблема выглядит так, как будто она раскопала довольно фундаментальное недоразумение с моей стороны, и я начинаю думать больше, чем когда-либо: «Хорошо, завтра я не должен писать какой-либо код, а вместо этого найти библиотеку с хорошим разделом CS и просто прочитайте все, что у них есть на шаблонах "! Интересно, а ты пока можешь мне помочь?
Итак, следующий код,
template <typename T> // or replace `typename` with `class`
struct Foo {
struct Bar {};
Foo(Bar) {}
};
Foo<float>::Bar x;
Foo<int> y (x);
не компилируется, поскольку x
имеет тип Foo<float>::Bar
, но для построения y
нам нужно Foo<int>::Bar
. Это нормально и ожидаемо, но теперь рассмотрим следующее:
template <int I>
struct Foo {
struct Bar {};
Foo(Bar) {}
};
Foo<0>::Bar x;
Foo<1> y (x);
Я надеялся / думал (хотя, к счастью, пока еще не полагался), что x
будет иметь тип Foo<0>::Bar
и для построения y
нам понадобится Foo<1>::Bar
, и как таковой он не будет компилироваться - как в предыдущем примере. Но похоже, что оба на самом деле имеют тип Foo<int>::Bar
, поэтому этот будет скомпилирован.
Итак, мне интересно, какова, во-первых, правильная терминология для описания этой разницы между параметризованным шаблоном typename / class и параметризованным целочисленным типом, какие другие различия в поведении это влечет за собой, и какой метод я могу использовать решить эту проблему и получить желаемое поведение для этого простого примера, чтобы Foo<0>
и Foo<1>
описывали несовместимые типы?
И перед этой поездкой в библиотеку приветствуются любые ссылки на "необходимые" онлайн-материалы для чтения на эту тему.
Спасибо.