C++ Modelo De Ambiguidade
Pergunta
Um amigo e eu estávamos discutindo modelos C++.Ele me perguntou o que este deve fazer:
#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);
}
A última linha principal tem dois razoável analisa.É 'b' o argumento de modelo ou é b > (c)
o argumento de modelo?
Embora, é fácil de compilar isso, e ver o que conseguimos, ficamos imaginando o que resolve a ambiguidade?
Solução
AFAIK seria compilado como new A<b>(c) > d
.Este é o único caminho razoável para analisá-lo IMHO.Se o analisador não pode assumir, em circunstâncias normais, um > final de um argumento de modelo, que seria o resultado é muito mais ambiguidade.Se você quiser que o outro, você deveria ter escrito:
new A<(b > c)>(d);
Outras dicas
Como afirmado por Leon & Lee, 14.2/3 (C++ '03) define explicitamente o comportamento.
C++ 0x contribui para a diversão com uma regra semelhante aplicando-se a >>
.O conceito básico, é que ao analisar um modelo de lista do argumento não aninhados >>
vai ser tratadas como duas distintas >
>
tokens e não o direito de mudança de operador:
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' e '#2' são equivalentes acima.
Isso, claro, correções de irritação com a necessidade de adicionar espaços em aninhadas especializações:
C<A<false>> c; // Parse error in C++ '98, '03 due to "right shift operator"
O padrão de C++ define que, se por um modelo de nome seguido por um <
, o <
é sempre o início do modelo de lista de argumentos e o primeiro não-aninhados >
é tomado como o fim do modelo de lista de argumentos.
Se se pretende que o resultado da >
operador de ser o argumento de modelo e, em seguida, você precisa colocar a expressão entre parênteses.Você não precisa de parênteses se o argumento era parte de um static_cast<>
ou outro modelo de expressão.
A avidez do lexer é, provavelmente, o fator determinante na ausência de parênteses para torná-lo explícito.Eu acho que o lexer não é ganancioso.