我有这个代码:

#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传递仿函数对象,以避免无用的复制构造函数调用。我期望以下输出:

F: 6
7

通过用 boost 替换 std::tr1 命名空间,它可以与 GCC >= 4.4.0、Visual Studio 2008 和 boost 一起正常工作。它仅不适用于新的 Visual Studio 2010 Express Beta 2 和 Release Candidate。

这个新的 C++ 功能在 vs2010 中是否有 bug?或者代码中有一些错误或误用?

有帮助吗?

解决方案

我想我找到了原因。这就是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(无参数),则类型为 void。
    • 如果 N>0,则类型为 typename F::template result<F(T1, T2,..., TN)>::type

错误消息是尝试这些后备措施的产物。提供一个 typedef result_typeint 我认为它应该有效。请注意,在 C++0x, ,这是不同的。它不依赖于 result_type 或一个 result 模板,因为它可以使用 decltype.

如果与 <functional> 它在 C++0x 模式下的 MSVC10 中失败,我想说,它闻起来像一个错误。但也许其他人知道发生了什么事。它可能(但不保证)与 <tr1/functional> 在 C++0x 模式下,如果该标头选择采用 decltype 方式而不是 ::result_type. 。我会输入 result_type - 这样我认为它应该始终有效,无论是否 tr1 使用标头或 c++0x 标头。


另请注意 boost::tr1 在其文档中说它不支持函数调用运算符(但它仅支持隐式转换为 T&).

其他提示

我在这里遇到了类似的问题: C ++函子防止不必要的副本对象

要使它汇编MSVC10,我不得不从的std :: unary_function得到我的函数对象。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top