템플릿 클래스의 구조체에서 C ++ 컴파일러 문제


13

다음 코드는 gcc 또는 clang으로 컴파일 되지 않습니다 .

template<class T>
class foo{};

template<class T>
class template_class_with_struct
{
    void my_method() {
        if(this->b.foo < 1);
    };

    struct bar
    {
        long foo;
    } b;
};

오류 메시지는

error: type/value mismatch at argument 1 in template parameter list for 'template<class T> class foo'    
    8 |         if(this->b.foo < 1);

오류는 templat 클래스 foo에 의해 발생합니다. <1 대신 <=를 쓰면 컴파일됩니다.

어떤 힌트를 주시겠습니까?

컴파일러 익스플로러 링크 https://godbolt.org/z/v6Tygo


7
컴파일러 버그라고 말하지만 msvc는 그것을 받아 들일 수있는 유일한 것입니다 :-/ Demo . 가능한 해결 방법 b.bar::foo또는 괄호 ( (this->b.foo) < 1)
Jarod42

답변:


1

GCC에서는

so.cpp:8:27: error: expected '>'
    if(this->b.foo < 1) 
                      ^

따라서 컴파일러 foo는 해당 줄에서 foo위 의 클래스를 참조하고 템플릿 인수를 기대 한다고 생각합니다 . 이것은 당신이보고있는 것과 유사합니다.

로 변경 <=하면 렉서에서 단일 토큰으로 토큰 화됩니다. 다음 단계에서도을 볼 수 <없으므로 혼동되지 않습니다.

long in과 이름이 같지 않도록 클래스를 변경하면 bar이 문제가 발생하지 않습니다. 또한 @ Jarod42는 귀하의 질문에 대한 의견에 제안을합니다 (자격 또는 더 많은 자격).

컴파일러는 단계별로 작성되며, 각 단계는 코드를 다음 단계를위한 더 나은 표현으로 변환하고 각 단계는 해당 표현으로 점점 더 복잡한 작업을 수행 할 수 있습니다.

처음에는 컴파일러가 코드를 "분석"하여 파일의 개별 문자를 토큰 스트림으로 변환합니다.이 행은 다음과 같이 표시됩니다.

// if(this->b.foo < 1) 
- keyword(if)
- left-paren
- keyword(this)
- operator(->)
- name(b)
- operator(.)

그리고 그것은에 도착합니다 foo. 아마 할 것

- name(foo)
- operator(<)
- number(1)
- right-paren

그러나 그것은 나에게 보일 때처럼 foo보입니다. 앞으로 보며 존재 <하는 사실과 사실을 보고 foo<class T>단일 토큰을 만들려고 foo< ...하지만 >완료 할 수는 없습니다 .

이것은 추측 일뿐입니다. 이름을 찾고 토큰을 결합 할 수있는 어휘 분석기를 지나는 단계 일 수 있습니다. 어쨌든 foo를 여러 번 사용하면 속임수입니다.


나는 당신의 설명을 이해하지만 컴파일러가 그렇게 행동해야한다는 것을 확신하지 못합니다. 어쩌면 이것은 다른 컴파일러의 버그로 필드에 있어야합니다. 때로는 링크 된 라이브러리 헤더 (cnt, count, counter ...와 같은 일반적인 이름) 내에있는 템플리트 클래스를 알 수 없습니다.
eactor

나는 그것이 버그라고 생각하지만 스펙이 무엇을 말하는지 모른다. 타사 헤더의 이름을 사용하면 문제가 발생하는 것이 C ++에서 일반적으로 발생합니다. 일반적으로 자격으로 해결할 수 있습니다.
루 프랑코
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.