혼란스러운 템플릿 오류
나는 clang을 가지고 놀다가 템플릿 오류에서 복구하기위한 힌트를 제공해야하는 "test / SemaTemplate / dependent-template-recover.cpp"(clang 배포판)를 우연히 발견했습니다.
모든 것을 최소한의 예제로 쉽게 제거 할 수 있습니다.
template<typename T, typename U, int N> struct X {
void f(T* t)
{
// expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
t->f0<U>();
}
};
clang에서 생성 한 오류 메시지 :
tpl.cpp:6:13: error: use 'template' keyword to treat 'f0' as a dependent template name
t->f0<U>();
^
template
1 error generated.
... 그러나 template
코드 구문이 정확하도록 키워드를 정확히 삽입해야하는 위치를 이해하기가 어렵습니다 .
ISO C ++ 03 14.2 / 4 :
멤버 템플릿 전문 분야의 이름이 뒤에 나타날 때. 또는-> postfix-expression에서 또는 규정 된 ID의 중첩 이름 지정자 뒤에 있고 postfix-expression 또는 규정 된 ID는 템플릿 매개 변수 (14.6.2)에 명시 적으로 의존하는 경우 멤버 템플릿 이름은 다음과 같아야합니다. 키워드 template가 앞에 붙습니다 . 그렇지 않으면 이름이 템플릿이 아닌 이름으로 간주됩니다.
In t->f0<U>();
f0<U>
은 ->
템플릿 매개 변수 뒤에 나타나고 명시 적으로 의존 U
하는 멤버 템플릿 전문화이므로 멤버 템플릿 전문화는 template
키워드 로 접두사로 지정해야합니다 .
그래서 변경 t->f0<U>()
에 t->template f0<U>()
.
다른 사람들이 지적한 것 외에도 때때로 컴파일러가 마음을 결정할 수 없으며 두 해석 모두 인스턴스화 할 때 대체 유효한 프로그램을 생성 할 수 있습니다.
#include <iostream>
template<typename T>
struct A {
typedef int R();
template<typename U>
static U *f(int) {
return 0;
}
static int f() {
return 0;
}
};
template<typename T>
bool g() {
A<T> a;
return !(typename A<T>::R*)a.f<int()>(0);
}
int main() {
std::cout << g<void>() << std::endl;
}
이전에 0
생략 했지만 삽입 할 때 인쇄 됩니다 . 코드가 무엇을하는지 알아 내기위한 연습으로 남겨 둡니다.template
f<int()>
1
캐럿이있는 지점 바로 앞에 삽입하십시오.
template<typename T, typename U, int N> struct X {
void f(T* t)
{
t->template f0<U>();
}
};
Edit: the reason for this rule becomes clearer if you think like a compiler.
Compilers generally only look ahead one or two tokens at once, and don't generally "look ahead" to the rest of the expression.
[Edit: see comment] The reason for the keyword is the same as why you need the typename
keyword to indicate dependent type names: it's telling the compiler "hey, the identifier you're about to see is the name of a template, rather than the name of a static data member followed by a less-than sign".
Excerpt from C++ Templates
The .template Construct A very similar problem was discovered after the introduction of typename. Consider the following example using the standard bitset type:
template<int N>
void printBitset (std::bitset<N> const& bs)
{
std::cout << bs.template to_string<char,char_traits<char>,
allocator<char> >();
}
The strange construct in this example is .template. Without that extra use of template, the compiler does not know that the less-than token (<) that follows is not really "less than" but the beginning of a template argument list. Note that this is a problem only if the construct before the period depends on a template parameter. In our example, the parameter bs depends on the template parameter N.
In conclusion, the .template notation (and similar notations such as ->template) should be used only inside templates and only if they follow something that depends on a template parameter.
참고URL : https://stackoverflow.com/questions/3786360/confusing-template-error
'your programing' 카테고리의 다른 글
Android Emulator : 기본적으로 실행할 AVD (Android Virtual Device) 선택 (0) | 2020.10.12 |
---|---|
HashMap은 다른 키에 대해 스레드로부터 안전합니까? (0) | 2020.10.12 |
왜`finally`의 리턴이`try`보다 우선합니까? (0) | 2020.10.12 |
Promise.all (). then () 해결? (0) | 2020.10.12 |
Python-virtualenv를 사용하여 수동으로 패키지 설치 (0) | 2020.10.12 |