1

我正在尝试修复一个库(entityx),该库当前无法使用 VS 2013 在 Windows 上编译。它可以在 Linux 上使用 gcc 编译,也可以在 Windows 上使用 MinGW 编译。

似乎问题出在 SFINAE - 我猜 VS 2013 没有正确忽略模板的替换失败。

Microsoft Connect 上有关于此问题的报告,请点击此处

在我深入研究 entityx之前,有一个问题示例(取自 Microsoft Connect 的报告):

#include <vector>
#include <future>

using namespace std;

typedef int async_io_op;

struct Foo
{
    //! Invoke the specified callable when the supplied operation completes
    template<class R> inline std::pair < std::vector < future < R >> , std::vector < async_io_op >> call(const std::vector<async_io_op> &ops, const std::vector < std::function < R() >> &callables);
    //! Invoke the specified callable when the supplied operation completes
    template<class R> std::pair < std::vector < future < R >> , std::vector < async_io_op >> call(const std::vector < std::function < R() >> &callables) { return call(std::vector<async_io_op>(), callables); }
    //! Invoke the specified callable when the supplied operation completes
    template<class R> inline std::pair<future<R>, async_io_op> call(const async_io_op &req, std::function<R()> callback);
    //! Invoke the specified callable when the supplied operation completes
    template<class C, class... Args> inline std::pair<future<typename std::result_of<C(Args...)>::type>, async_io_op> call(const async_io_op &req, C callback, Args... args);
};

int main(void)
{
    Foo foo;
    std::vector<async_io_op> ops;
    std::vector < std::function < int() >> callables;
    foo.call(ops, std::move(callables));
    return 0;
}

尝试编译时出现以下错误:

错误 C2064:术语不计算为采用 0 个参数的函数

c:\program 文件 (x86)\microsoft visual studio 12.0\vc\include\xrefwrap 58

显然,我们可以std::enable_if用来解决这个问题。但是,我无法弄清楚如何。

有谁知道我可以如何解决这个编译错误?

编辑:VS 2013 的完整输出:

1>------ Build started: Project: VS2013_SFINAE_Failure, Configuration: Debug Win32 ------
1>  test_case.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(58): error C2064: term does not evaluate to a function taking 0 arguments
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(118) : see reference to class template instantiation 'std::_Result_of<_Fty,>' being compiled
1>          with
1>          [
1>              _Fty=std::vector<std::function<int (void)>,std::allocator<std::function<int (void)>>>
1>          ]
1>          c:\users\jarrett\downloads\vs2013_sfinae_failure\vs2013_sfinae_failure\test_case.cpp(25) : see reference to class template instantiation 'std::result_of<std::vector<std::function<int (void)>,std::allocator<_Ty>> (void)>' being compiled
1>          with
1>          [
1>              _Ty=std::function<int (void)>
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
4

1 回答 1

3

VS2013 编译代码,如果你std::result_of用它的decltype+std::declval等效替换。所以将最后一个Foo::call()定义更改为

template<class C, class... Args>
inline pair<future<decltype(declval<C>()(declval<Args>()...))>, async_io_op> 
call(const async_io_op& req, C callback, Args... args);

如果我正确理解错误,它与此处描述的缺陷有关,但令人惊讶的是 GCC 和 clang 都设法编译result_of代码而没有错误。

于 2014-02-11T03:31:31.160 回答