템플릿 템플릿 클래스가있는 GCC / C ++ 17의 문제


10

다음 2 가지 과부하를 고려하십시오

template<typename T>
bool test() {
    return true;
}

template<template<typename ...> class T>
bool test() {
    return false;
}

첫 번째 클래스는 일반 클래스에서 작동하고 두 번째 클래스는 인스턴스화되지 않은 템플릿에서 작동합니다. 예를 들어 :

    std::cout<<test<int>()<<std::endl; <-- this yields 1
    std::cout<<test<std::list>()<<std::endl; <--this yields 0

이제 다음 템플릿 기능을 고려하십시오.

template<typename U>
bool templfun(){
    struct A{
        bool f(){
            return test<A>(); // <-- this gives an error
        }
    };
    return test<A>();  // <-- this is ok
}

GCC에서는 Clang이 컴파일하는 동안 모호한 과부하 해결에 오류가 발생합니다. 흥미롭게도 test ()에 대한 두 번째 호출은 오류를 생성하지 않습니다 (GCC에서도). 또한 template<typename U>templfun 위에 있는 것을 제거하면 gcc는 불평을 멈 춥니 다.

이것은 GCC의 버그입니까, 아니면 불법 코드입니까?

답변:


4

GCC가 잘못되었습니다. struct AA는 템플릿 실체 분명하지만 이 아닌 템플릿 (그것이로 시작하지 않는 한 template, 그래서 모호함이없는 키워드).

확인하기 위해 type 매개 변수의 이름을 바꾸어 G ++이 템플릿 템플릿 오버로드를 사용하려고한다는 것을 알 수 있습니다.

template <typename X>
bool test() {
    return true;
}

template <template <typename...> class Y>
bool test() {
    return false;
}

template <typename U>
bool templfun() {
    struct A {
        bool f() {
            return test<A>(); // <-- this gives an error
        }
    };
    return test<A>(); // <-- this is ok
}

bool run() {
    return templfun<int>();
}

G ++ 출력 : ( godbolt 링크 )

<source>:15:27: error: call of overloaded 'test<templfun() [with U = int]::A>()' is ambiguous
   15 |             return test<A>(); // <-- this gives an error
      |                    ~~~~~~~^~

<source>:2:6: note: candidate: 'bool test() [with X = templfun() [with U = int]::A]'
    2 | bool test() {
      |      ^~~~

<source>:7:6: note: candidate: 'bool test() [with Y = templfun()::A]'
    7 | bool test() {
      |      ^~~~

분명히 " candidate: 'bool test() [with Y = templfun()::A]'"는 가짜입니다.

C ++ 11 이전에는 로컬 형식이 템플릿 인수로 허용되지 않았으므로 (C ++ 03 § 14.3.1.2 참조) G ++ 구현의 복잡성을 설명 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.