Pergunta

Eu tenho este código:

#include <iostream>
#include <functional>

struct A
{
    int operator()(int i) const {
        std::cout << "F: " << i << std::endl;
        return i + 1;
    }
};

int main()
{
    A a;
    std::tr1::function<int(int)> f = std::tr1::ref(a);
    std::cout << f(6) << std::endl;
}

O objetivo é passar no objeto Functor por um reference_wrapper, de forma a evitar chamadas inúteis de cópias. Eu espero a seguinte saída:

F: 6
7

Funciona corretamente com GCC> = 4.4.0, Visual Studio 2008 e com Boost substituindo o espaço para nome STD :: Tr1 por Boost. Ele não funciona apenas com o novo Visual Studio 2010, expressa a Beta 2 e o candidato a lançar.

Esses novos recursos C ++ são com bugs no vs2010? Ou há algum erro ou uso indevido no código?

Foi útil?

Solução

Acho que encontrei o motivo. É isso que tr1 3.4/2 diz sobre result_of<T(A1, A2, ..., AN)>::type, usado na determinação do tipo de retorno de reference_wrapper<T>::operator():

A implementação pode determinar o membro do tipo por qualquer meio que produz o tipo exato da expressão F (T1, T2, ..., TN) para os tipos fornecidos. [Nota: a intenção é que as implementações possam usar ganchos especiais do compilador - nota

E então o parágrafo 3:

Se F não for um objeto de função definido pela biblioteca padrão e se a implementação não puder determinar o tipo de expressão f (t1, t2, ..., tn) ou se a expressão for mal formada, a implementação deve usar O processo a seguir para determinar o membro do tipo:

  • Se F é um tipo de classe possivelmente qualificado para CV sem membro nomeado result_type ou se typename F::result_type não é um tipo:
    • Se n = 0 (sem argumentos), o tipo é nulo.
    • Se n> 0, o tipo é typename F::template result<F(T1, T2,..., TN)>::type

A mensagem de erro é um artefato de experimentar essas deformações. Fornecer um typedef para result_type para int E isso deve funcionar, eu acho. Observe que em C++0x, isso é diferente. Não depende de result_type ou a result modelo, já que pode usar decltype.

Se com <functional> Ele falha com o MSVC10 no modo C ++ 0x, cheira a um bug, eu diria. Mas talvez alguém saiba o que está acontecendo. Pode (mas não é garantido) trabalhar com <tr1/functional> no modo C ++ 0x se esse cabeçalho optar por tomar o decltype caminho em vez de ::result_type. Eu digitaria result_type - Dessa forma, acho que sempre deve funcionar, independentemente de se o tr1 Cabeçalho é usado ou o c++0x cabeçalho.


Observe também isso boost::tr1 diz em sua documentação que ele não suporta o operador de chamada de função (mas apenas suporta conversões implícitas para T&).

Outras dicas

Encontro um problema semelhante aqui:Evite cópias desnecessárias de objetos de functor C ++

Para compilar no MSVC10, tive que derivar meu objeto de função do std :: unary_function.

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