我有这个代码:
#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;
}
目的是通过reference_wrapper传递functor对象,以避免无用的复制costructor调用。
我期待以下输出:
F: 6
7
它适用于GCC> = 4.4.0,Visual Studio 2008,并通过用boost替换std :: tr1命名空间来提升。它仅适用于新的Visual Studio 2010 Express Beta 2和Release Candidate。
这个新的C ++功能在vs2010中有漏洞吗?
或者代码中有一些错误或误用?
我想我找到了原因。这就是TR1 3.4/2
说的 result_of<T(A1, A2, ..., AN)>::type
,用于确定返回类型 reference_wrapper<T>::operator()
:
实现可以通过任何方式确定类型成员,该方法产生给定类型的表达式f(t1,t2,...,tN)的确切类型。 [注意:目的是允许实现使用特殊的编译器钩子 - 结束注意]
然后第3段:
如果F不是标准库定义的函数对象,并且如果实现无法确定表达式f(t1,t2,...,tN)的类型或表达式是否格式错误,则实现应使用以下过程确定类型成员:
- 如果F是一个可能是cv限定的类类型,没有名为的成员
result_type
或者如果 typename F::result_type
不是一种类型:
- 如果N = 0(无参数),则type为void。
- 如果N> 0,则键入
typename F::template result<F(T1, T2,..., TN)>::type
错误消息是尝试这些后备的人工制品。提供typedef result_type
至 int
我认为它应该有效。注意在 C++0x
,这是不同的。它不依赖 result_type
或者a result
模板,因为它可以使用 decltype
。
如果有 <functional>
它会在C ++ 0x模式下以MSVC10失败,它会闻起来像一个bug,我会说。但也许别人知道发生了什么。它可能(但不保证)可以使用 <tr1/functional>
在C ++ 0x模式下,如果该标头选择采取 decltype
方式而不是 ::result_type
。我会打字 result_type
- 这种方式我认为它应该始终有效,无论是否 tr1
使用标头或 c++0x
头。
还要注意 boost::tr1
在它的文档中说它不支持函数调用操作符(但它只支持隐式转换) T&
)。
我在这里遇到类似的问题:
防止不必要的C ++仿函数对象副本
为了使它在MSVC10上编译,我必须从std :: unary_function派生我的函数对象。