I have this code:
#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;
}
The aim is to pass the functor object by a reference_wrapper, in a way to avoid useless copy costructor calls.
I expect the following output:
F: 6
7
It works correctly with GCC >= 4.4.0, Visual Studio 2008 and with boost by substituting std::tr1 namespace with boost. It only doesn’t work with the new Visual Studio 2010 both Express Beta 2 and Release Candidate.
Are this new C++ features bugged in vs2010?
Or there is some mistake or misuse in the code?
I think i found the reason. This is what TR1
3.4/2says aboutresult_of<T(A1, A2, ..., AN)>::type, used in the determination of the return type ofreference_wrapper<T>::operator():And then paragraph 3:
The error message is an artefact of trying these fall-backs. Provide a typedef for
result_typetointand it should work, i think. Notice that inC++0x, this is different. It does not rely onresult_typeor aresulttemplate, since it can usedecltype.If with
<functional>it fails with MSVC10 in C++0x mode, it smells like a bug, i would say. But maybe someone else knows what’s going on. It may (but is not guaranteed to) work with<tr1/functional>in C++0x mode if that header chooses to take thedecltypeway instead of::result_type. I would typedefresult_type– that way i think it should always work regardless of whether thetr1header is used or thec++0xheader.Also notice that
boost::tr1says in its documentation that it does not support the function call operator (but it merely supports implicit conversions toT&).