your programing

혼란스러운 템플릿 오류

lovepro 2020. 10. 12. 07:59
반응형

혼란스러운 템플릿 오류


나는 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생략 했지만 삽입 할 때 인쇄 됩니다 . 코드가 무엇을하는지 알아 내기위한 연습으로 남겨 둡니다.templatef<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

반응형