문제
친구와 저는 C++ 템플릿에 대해 논의하고 있었습니다.그는 나에게 이것이 무엇을 해야 하는지 물었습니다.
#include <iostream>
template <bool>
struct A {
A(bool) { std::cout << "bool\n"; }
A(void*) { std::cout << "void*\n"; }
};
int main() {
A<true> *d = 0;
const int b = 2;
const int c = 1;
new A< b > (c) > (d);
}
main의 마지막 줄에는 두 가지 합리적인 구문 분석이 있습니다.'b'는 템플릿 인수입니까, 아니면 b > (c)
템플릿 인수?
이를 컴파일하고 무엇을 얻는지 확인하는 것은 쉽지 않지만 모호성을 해결하는 방법이 무엇인지 궁금합니다.
해결책
AFAIK는 다음과 같이 컴파일됩니다. new A<b>(c) > d
.이것이 IMHO를 구문 분석하는 유일한 합리적인 방법입니다.파서가 일반적인 상황에서 템플릿 인수를 > end로 가정할 수 없다면 훨씬 더 모호해질 것입니다.다른 방법으로 원한다면 다음과 같이 작성해야 합니다.
new A<(b > c)>(d);
다른 팁
Leon & Lee가 설명한 대로 14.2/3(C++ '03)에서는 이 동작을 명시적으로 정의합니다.
C++ '0x는 비슷한 규칙을 적용하여 재미를 더합니다. >>
.기본 개념은 템플릿 인수 목록을 구문 분석할 때 중첩되지 않은 >>
두 개의 서로 다른 것으로 취급됩니다 >
>
오른쪽 시프트 연산자가 아닌 토큰:
template <bool>
struct A {
A(bool);
A(void*);
};
template <typename T>
class C
{
public:
C (int);
};
int main() {
A<true> *d = 0;
const int b = 2;
const int c = 1;
new C <A< b >> (c) > (d); // #1
new C <A< b > > (c) > (d); // #2
}
위의 '#1'과 '#2'는 동일합니다.
물론 이는 중첩된 전문화에 공백을 추가해야 하는 성가심을 해결합니다.
C<A<false>> c; // Parse error in C++ '98, '03 due to "right shift operator"
C++ 표준은 템플릿 이름 뒤에 <
, <
항상 템플릿 인수 목록의 시작이고 첫 번째 중첩되지 않은 인수 목록입니다. >
템플릿 인수 목록의 끝으로 간주됩니다.
만약 당신이 그 결과를 의도했다면 >
연산자가 템플릿 인수인 경우 표현식을 괄호로 묶어야 합니다.인수가 a의 일부인 경우 괄호가 필요하지 않습니다. static_cast<>
또는 다른 템플릿 표현식.
어휘 분석기의 탐욕은 아마도 이를 명시적으로 만드는 괄호가 없는 경우 결정적인 요소일 것입니다.나는 어휘 분석기가 욕심이 없다고 생각합니다.