Pergunta

Observation: the codes pasted below were tested only with GCC 4.4.1, and I'm only interested in them working with GCC.

Olá,

Não foi por apenas algumas vezes que tropecei em uma declaração de construção de objetos que não entendi, e foi apenas hoje que notei o que a ambiguidade estava sendo introduzida por ela. Vou explicar como reproduzi -lo e gostaria de saber se há uma maneira de corrigi -lo (C ++ 0x permitido). Aqui vai.

Suponha que exista uma classe cujo construtor pegue apenas um argumento, e esse tipo de argumento é outra classe com um construtor padrão. Por exemplo:

struct ArgType {};

class Class
{
public:
    Class(ArgType arg);
};

Se eu tentar construir um objeto do tipo Class Na pilha, recebo uma ambiguidade:

Class c(ArgType()); // is this an object construction or a forward declaration
                    // of a function "c" returning `Class` and taking a pointer
                    // to a function returning `ArgType` and taking no arguments
                    // as argument? (oh yeh, loli haets awkward syntax in teh
                    // saucecode)

Eu digo que é uma construção de objetos, mas o compilador insiste que é uma declaração a seguir dentro do corpo da função. Para você que ainda não entende, aqui está um exemplo totalmente funcional:

#include <iostream>

struct ArgType {};
struct Class {};

ArgType func()
{
    std::cout << "func()\n";
    return ArgType();
}

int main()
{
    Class c(ArgType());

    c(func); // prints "func()\n"
}

Class c(ArgType funcPtr()) // Class c(ArgType (*funcPtr)()) also works
{
    funcPtr();
    return Class();
}

Tão bem, exemplos suficientes. Alguém pode me ajudar a contornar isso sem fazer nada anti-idiomático (sou desenvolvedor de bibliotecas e pessoas como bibliotecas idiomáticas)?

- Editar

Deixa para lá. Este é um idiota de A análise mais irritante: por que um A (()) não; trabalhar?.

Obrigado, SBI.

Foi útil?

Solução

Isso é conhecido como "C ++ mais irritante análise". Ver aqui e aqui.

Outras dicas

Vamos simplificar um pouco.

int f1();

O que é isso? O compilador (e eu) dizem que é uma declaração avançada para uma função que retorna um número inteiro.

Que tal agora?

int f2(double );

O compilador (e eu) dizem que é uma declaração avançada para uma função que assume um argumento duplo e retornando um int.

Então você já tentou:

ClassType c = ClassType(ArgType());

Confira o Lite C ++ FAQ em construtores por Explicações e exemplos

Com base no "C ++ 0x permitido", a resposta certa é (provavelmente) para alterar a definição para:

Class c(ArgType {});

Simples, simples e coloca o ônus inteiramente no usuário da biblioteca, não no autor!

EDIT: Sim, o CTOR é chamado-C ++ 0x adiciona a inicialização da lista como uma maneira inequívoca de delimitar listas de inicializador. Não pode ser incorreto como em sua amostra, mas, caso contrário, o significado é aproximadamente o mesmo como se você usasse parênteses. Ver N3000, o terceiro ponto de bala sob §8.5.4/3. Você pode escrever um CTOR para receber uma lista de inicializadores como um único argumento, ou os itens na lista de inicializadores podem ser correspondidos com os argumentos do CTOR individualmente.

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