Visual Studio 2010和std :: function [英] Visual Studio 2010 and std::function
问题描述
我有这样的代码:
#include< iostream>
#include< functional>
struct A
{
int operator()(int i)const {
std :: cout<< F:<<我<<的std :: ENDL;
返回i + 1;
}
};
int main()
{
A a;
std :: tr1 :: function< int(int)> f = std :: tr1 :: ref(a);
std :: cout<< f(6)<<的std :: ENDL;
}
目标是通过reference_wrapper传递函子对象,避免无用的副本构造函数调用。
我期望以下输出:
F:6
7
$ c它可以正常使用GCC> = 4.4.0,Visual Studio 2008,并通过使用boost来替代std :: tr1命名空间来提升性能。它只适用于新的Visual Studio 2010 Express beta 2和Release Candidate。
这个新的C ++功能在vs2010中有bug吗?
或者在代码中存在一些错误或误用?
解决方案我想我找到了原因。这就是TR1 3.4 / 2
关于 result_of ,用于确定 reference_wrapper< T> :: operator()
的返回类型:
< blockquote>
实现可以通过任何方法来确定类型成员,这些方法会为给定类型生成表达式f(t1,t2,...,tN)的确切类型。 [注:意图是允许实现使用特殊的编译器钩子 - 结束注释]
然后段落3:
如果F不是由标准库定义的函数对象,并且实现无法确定表达式f(t1,t2, ...,tN),或者表达式格式不正确,实现将使用以下过程来确定类型成员:
- 如果F是可能的cv限定类类型,但没有名为
result_type
的成员,或者如果 typename F :: result_type
不是a类型:
- 如果N = 0(无参数),则类型为void。类型是
typename F :: template result< F(T1,T2,...,TN)> :: type
错误消息是尝试这些回退的人造物。为 result_type
提供一个typedef以 int
,我认为它应该起作用。请注意,在 C ++ 0x
中,这是不同的。它不依赖 result_type
或结果
模板,因为它可以使用 decltype code>。
$ b $ 如果使用< functional>
,它在C ++ 0x模式下失败,MSVC10会发出臭虫, 我会说。但也许别人知道发生了什么。它可能(但不能保证)在C ++ 0x模式下使用< tr1 / functional>
,如果该头文件选择采用 decltype
方式而不是 :: result_type
。我会typedef result_type
- 这样,我认为无论是使用 tr1
头还是 c ++ 0x
标头。
另请注意, boost :: tr1
它不支持函数调用操作符(但它只支持隐式转换为 T&
)。
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/2
says about result_of<T(A1, A2, ..., AN)>::type
, used in the determination of the return type of reference_wrapper<T>::operator()
:
The implementation may determine the type member via any means that produces the exact type of the expression f(t1, t2, ..., tN) for the given types. [Note: The intent is that implementations are permitted to use special compiler hooks —end note]
And then paragraph 3:
If F is not a function object defined by the standard library, and if either the implementation cannot determine the type of the expression f(t1, t2, ..., tN) or if the expression is ill-formed, the implementation shall use the following process to determine the type member:
- If F is a possibly cv-qualified class type with no member named
result_type
or if typename F::result_type
is not a type:
- If N=0 (no arguments), type is void.
- If N>0, type is
typename F::template result<F(T1, T2,..., TN)>::type
The error message is an artefact of trying these fall-backs. Provide a typedef for result_type
to int
and it should work, i think. Notice that in C++0x
, this is different. It does not rely on result_type
or a result
template, since it can use decltype
.
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 the decltype
way instead of ::result_type
. I would typedef result_type
- that way i think it should always work regardless of whether the tr1
header is used or the c++0x
header.
Also notice that boost::tr1
says in its documentation that it does not support the function call operator (but it merely supports implicit conversions to T&
).
这篇关于Visual Studio 2010和std :: function的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!