Câu trả lời ngắn: Bất cứ khi nào đề cập đến tên lồng nhau là tên phụ thuộc, tức là lồng trong mẫu bản mẫu có tham số không xác định.
Câu trả lời dài: Có ba cấp thực thể trong C++: giá trị, loại và mẫu. Tất cả những cái đó có thể có tên, và cái tên đó không nói cho bạn biết tầng thực thể nào của nó. Thay vào đó, thông tin về bản chất của thực thể tên phải được suy ra từ ngữ cảnh.
Bất cứ khi nào suy luận này là không thể, bạn phải xác định nó:
template <typename> struct Magic; // defined somewhere else
template <typename T> struct A
{
static const int value = Magic<T>::gnarl; // assumed "value"
typedef typename Magic<T>::brugh my_type; // decreed "type"
// ^^^^^^^^
void foo() {
Magic<T>::template kwpq<T>(1, 'a', .5); // decreed "template"
// ^^^^^^^^
}
};
đây tên Magic<T>::gnarl
, Magic<T>::brugh
và Magic<T>::kwpq
đã được expliciated, bởi vì nó không thể nói: Kể từ Magic
là một mẫu, các rất thiên nhiên thuộc loại Magic<T>
tùy thuộc vào T
- có thể có các chuyên ngành hoàn toàn khác với mẫu chính, chẳng hạn.
Điều gì làm cho Magic<T>::gnarl
tên phụ thuộc là thực tế rằng chúng tôi đang ở trong định nghĩa mẫu, trong đó T
không xác định. Nếu chúng ta sử dụng Magic<int>
, điều này sẽ khác, vì trình biên dịch biết (bạn hứa!) định nghĩa đầy đủ của Magic<int>
.
(Nếu bạn muốn tự mình kiểm tra, đây là định nghĩa mẫu của Magic
mà bạn có thể sử dụng. Hãy tha thứ sử dụng constexpr
trong đặc biệt cho ngắn gọn; nếu bạn có trình biên dịch cũ, hãy thay đổi hằng số thành viên tĩnh khai báo với pre C-++ hình thức kiểu cũ 11)
template <typename T> struct Magic
{
static const T gnarl;
typedef T & brugh;
template <typename S> static void kwpq(int, char, double) { T x; }
};
template <> struct Magic<signed char>
{
// note that `gnarl` is absent
static constexpr long double brugh = 0.25; // `brugh` is now a value
template <typename S> static int kwpq(int a, int b) { return a + b; }
};
cách sử dụng:.
int main()
{
A<int> a;
a.foo();
return Magic<signed char>::kwpq<float>(2, 3); // no disambiguation here!
}
http://stackoverflow.com/questions/610245/where-and-why-do- i-have-to-put-template-and-typename-on-dependent-name –