여기서 '템플릿'키워드가 필요한 이유는 무엇입니까?


9

다음 코드가 있습니다.

template <typename TC>
class C
{
    struct S
    {
        template <typename TS>
        void fun() const
        {}
    };

    void f(const S& s)
    {
        s.fun<int>();
    }
};

// Dummy main function
int main()
{
    return 0;
}

gcc 9.2와 clang (9.0)을 사용하여이를 빌드 할 때 template키워드를 호출해야하기 때문에 컴파일 오류가 발생합니다 fun. 클랑 쇼 :

error: use 'template' keyword to treat 'fun' as a dependent template name
        s.fun<int>();
          ^
          template 

컴파일러 자체가 템플릿 자체가 아니기 때문에 fun의 컨텍스트에서 종속 이름 이라고 생각하는 이유를 이해하지 못합니다 . 템플릿 대신 일반 클래스로 변경 하면 오류가 사라집니다. 그러나 나는 왜 처음부터 오류가 있어야하는지 알지 못합니다 .ffCSfTC .

이상하게도 MSVC 19.22는 이것을 잘 컴파일합니다.


노트

"템플릿"및 "typename"키워드어디에 그리고 왜 사용해야 합니까? 이것은 S실제로 종속 이름 인 f경우에도 현재 인스턴스화의 구성원이라는 사실이 아니라면 종속되지 않는 특별한 경우를 고려하십시오 .


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Bhargav Rao

답변:


10

고려 :

template<typename T>
struct C
{
    struct S
    {
        int a = 99;
    };

    void f(S s, int i)
    {
        s.a<0>(i);
    }
};

template<>
struct C<long>::S
{
    template<int>
    void a(int)
    {}
};

int main()
{
    C<int>{}.f({}, 0); // #1
    C<long>{}.f({}, 0); // #2
}

s.a<0>(i)는 두 개의 비교 연산 <과를 포함하는 표현식으로 구문 분석되며 이는 ># 1에는 적합하지만 # 2에는 실패합니다.

이 경우 변경s.template a<0>(i)다음 # 2는 OK입니다 # 1이 실패합니다. 따라서 template키워드는 여기서 중복되지 않습니다.

MSVC는 표현식을 해석 할 수 있습니다s.a<0>(i) 동일한 프로그램 내에서 두 가지 방식으로 있습니다. 그러나 이것은 표준에 따라 올바르지 않습니다. 각 표현식에는 컴파일러가 처리 할 구문 분석이 하나만 있어야합니다.


나는 아직도 이것을 완전히 이해하지 못한다. 귀하의 예는이 경우 전문화 C또는 다른 것을 사용 하지만 둘 다 인스턴스화 할 수는 없음을 보여줍니다 . 여기서 template키워드는 IMHO가 불필요 합니다. S어느 C것이 선택하는지에 따라 선택 됩니다. template키워드가 없으면 둘 다 인스턴스화 할 수 있으며 f의 동작은 인스턴스마다 다릅니다.
마틴

2
@Martin 요점은 각 토큰은 소스 파일에서 하나의 구문 역할을 가져야한다는 것입니다. 예를 들어, 토큰 <이 한 템플릿 인스턴스화에서 비교 연산자이고 다른 인스턴스화에서 여는 꺾쇠 괄호가되는 것은 좋지 않습니다 . 이는 컴파일러가 템플릿을 AST로 구문 분석 할 수 있도록하기위한 것입니다 (템플릿 유형에 대한 자리 표시 자와 함께).
ecatmur

말이 되네요 감사!
마틴

7

fun의 템플릿 매개 변수에 따라 템플릿 기능 일 수도 있고 존재하지 않을 수도 있습니다 class C.

당신이 전문화 할 수 있기 때문입니다 S 하지 않고 전문화 입니다 C.

template <> struct C<int>::S {};

컴파일러는 fun템플릿 템플릿 class C을 대체하기 전에 처음 볼 때 템플릿이 템플릿 인지 아닌지를 알고 싶어하기 때문에 template필요합니다.


1
마음 ... 날

이에 대한 후속 조치는의 새로운 정의에 S액세스 할 수 있는지 여부 f입니다. 그들이 할 수 없다면 f어쨌든 그들을 볼 수 없기 때문에이 제한을 갖는 것은 의미 가 없습니다.
마틴

@Martin GCC, Clang 및 MSVC에서 모두 f찾습니다.
HolyBlackCat

@bolov 그래, 당신 은 다른 많은 것들을 전문화 할 수 있습니다 .
HolyBlackCat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.