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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top