【问题标题】:Visual Studio 2010 and std::functionVisual Studio 2010 和 std::function
【发布时间】:2011-01-26 09:15:21
【问题描述】:

我有这个代码:

#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;
}

目的是通过引用包装器传递函子对象,以避免无用的复制构造函数调用。 我希望得到以下输出:

F: 6
7

它可以在 GCC >= 4.4.0、Visual Studio 2008 和 boost 中正常工作,方法是将 std::tr1 命名空间替换为 boost。它仅不适用于新的 Visual Studio 2010 Express Beta 2 和 Release Candidate。

这个新的 C++ 功能在 vs2010 中是否存在错误? 还是代码有错误或误用?

【问题讨论】:

  • @litb:我认为 OP 在使用 std::tr1::ref 模板类和 not VS2010 上的提升方面存在问题。
  • 这里是vs2010的构建输出:pastebin.com/YQf4Qe8W
  • 更多细节:包含 而不是 的相同代码适用于 vs2008,但 Steel 不适用于 vs2010。 vs2010 的 标头(及其依赖项)的内置实现似乎支持对 reference_wrapper 对象的函数调用调用......但它无法编译:(

标签: c++ visual-studio-2010 functional-programming c++11 functor


【解决方案1】:

我想我找到了原因。这就是 TR1 3.4/2 所说的关于 result_of&lt;T(A1, A2, ..., AN)&gt;::type 的内容,用于确定 reference_wrapper&lt;T&gt;::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&lt;F(T1, T2,..., TN)&gt;::type

错误消息是尝试这些回退的人工制品。为result_typeint 提供一个typedef,我认为它应该可以工作。请注意,在 C++0x 中,这是不同的。它不依赖result_typeresult 模板,因为它可以使用decltype

如果使用 &lt;functional&gt; 在 C++0x 模式下使用 MSVC10 失败,我会说,它闻起来像一个错误。但也许其他人知道发生了什么。如果该标头选择采用decltype 方式而不是::result_type,它可能(但不保证)在C++0x 模式下与&lt;tr1/functional&gt; 一起工作。我会 typedef result_type - 这样我认为无论是使用 tr1 标头还是 c++0x 标头,它都应该始终有效。


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

【讨论】:

【解决方案2】:

我在这里遇到了类似的问题: Prevent unnecessary copies of C++ functor objects

为了让它在 MSVC10 上编译,我必须从 std::unary_function 派生我的函数对象。

【讨论】:

    猜你喜欢
    • 2015-06-08
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    相关资源
    最近更新 更多