Я - diffing бок о бок целый день, и у меня нет долбаного' 22-дюймового монитора. Я не знаю, буду ли я когда-нибудь. Это, конечно, малоинтересно для программистов только для записи, наслаждающихся кодирующими стрелку и строками с 300 символами.
Я споткнулся, когда впервые унаследовал шаблонный класс от другого шаблонного класса:
template<typename T>
class Base {
int a;
};
template<typename T>
class Derived : public Base<T> {
void func() {
a++; // error! 'a' has not been declared
}
};
Проблема в том, что компилятор не знает, Base
будет шаблоном по умолчанию или специализированным. Специализированная версия может не иметь в качестве члена int a
, поэтому компилятор не предполагает, что он доступен. Но вы можете сообщить компилятору, что он будет там, с помощью директивы using
:
template<typename T>
class Derived : public Base<T> {
using Base<T>::a;
void func() {
a++; // OK!
}
};
В качестве альтернативы вы можете явно указать, что вы используете член T
:
void func {
T::a++; // OK!
}
Это меня тогда расстроило:
#include <vector>
using std::vector;
struct foo {
template<typename U>
void vector();
};
int main() {
foo f;
f.vector<int>(); // ambiguous!
}
Последняя строка в main неоднозначна, потому что компилятор не только ищет вектор
в foo
], но также как неквалифицированное имя, начиная с main
. Таким образом, он находит как std :: vector
, так и foo :: vector
. Чтобы исправить это, вы должны написать
f.foo::vector<int>();
GCC не заботится об этом и принимает приведенный выше код, выполняя интуитивно понятную вещь (вызывая член), другие компиляторы работают лучше и предупреждают, как comeau:
"ComeauTest.c", line 13: warning: ambiguous class member reference -- function
template "foo::vector" (declared at line 8) used in preference to
class template "std::vector" (declared at line 163 of
"stl_vector.h")
f.vector<int>(); // ambiguous!
Out of scope class member function definition:
template <typename T>
class List { // a namespace scope class template
public:
template <typename T2> // a member function template
List (List<T2> const&); // (constructor)
…
};
template <typename T>
template <typename T2>
List<T>::List (List<T2> const& b) // an out-of-class member function
{ // template definition
…
}