Visual Studio 2010 e STD :: Função
-
19-09-2019 - |
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?
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 setypename 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.