C++ c++;编译错误涉及方法重载的2个模板函数

C++ c++;编译错误涉及方法重载的2个模板函数,c++,templates,C++,Templates,在下面的代码中,单独编译每个模板函数不会导致错误,但将它们放在一起时会发生编译错误。有人能告诉我为什么,以及如何修复它吗 #include "stdafx.h" #include <iostream> void f(int a, int b) { std::cout << "MyFunctionI(" << a << ',' << b << ")\n"; } template <typename CALL

在下面的代码中,单独编译每个模板函数不会导致错误,但将它们放在一起时会发生编译错误。有人能告诉我为什么,以及如何修复它吗

#include "stdafx.h"
#include <iostream>


void f(int a, int b)
{
    std::cout << "MyFunctionI(" << a << ',' << b << ")\n";
}

template <typename CALLABLE, typename... ARGS>
typename std::enable_if<std::is_void<std::result_of_t<CALLABLE(ARGS&&...)>>::value, int>::type
DoFunction(CALLABLE fn, ARGS&&... args)
{
    fn(args...);
    return 0;
}
template <typename CALLABLE, typename... ARGS>
typename std::enable_if<std::is_void<std::result_of_t<CALLABLE(ARGS&&...)>>::value, int>::type
DoFunction(const int flag, CALLABLE fn, ARGS&&... args)
{
    fn(args...);
    return 0;
}


int main()
{
    int nId1 = DoFunction(f, 1, 2);
    int nId2 = DoFunction(1111, f, 1, 2);

    return 0;
}
#包括“stdafx.h”
#包括
空f(整数a,整数b)
{
std::cout c:\program files(x86)\microsoft visual studio 14.0\vc\include\type\u traits(1469):注意:使用以下模板参数:
1> c:\ProgramFiles(x86)\microsoft visual studio 14.0\vc\include\type\u traits(1469):注意:“\u Callable=std::ios\u base::iostate”
1> c:\ProgramFiles(x86)\microsoft visual studio 14.0\vc\include\type\u traits(1469):注意:“\u Types={int}”

附加信息,如果我不使用方法重载,即为模板函数使用不同的名称,编译器不会报告错误。

在模板变量函数上使用
std::result\u的方法在c++14中有效,但在c++11中无效

引用此处的文档():

如C++11中所述,
std::result_在
F(ArgTypes…
格式错误时(例如
F
根本不是可调用类型时)将无法编译。C++14将其更改为SFINAE(当
F
不可调用时,
std::result_的
根本没有类型成员)

std::result_背后的动机是确定调用FunctionObject的结果,特别是如果不同参数集的结果类型不同

总结一下:这个错误是由c++11版本的函数中如何实现模板类型推断引起的。它与c++14的预期一样工作,因此如果这是一个有效的选项,它可能是最好的解决方案

我可以确认,鉴于
-std=c++14
标志,它可以编译gcc和clang的最新版本并与之一起使用(但在
-std=c++11
时失败)


编辑:OP已使用C++14

代码实际上使用了只在C++14中出现的
std::result\u of\u t
,因此我上面的评论不适用

此外,该代码实际上也可以在C++11中使用
typename std::result\u of::type
而不是
std::result\u of of the t
(使用clang测试)


所以我不确定出了什么问题。可能是MSVC的STL实现中的错误?

正确地解决了它。MSVS2015 update2上也是如此。我建议您交换函数,这可能会有帮助。交换函数没有帮助:-(好吧,我传递给两个模板函数的“f”函数都是可调用类型,应该编译时不会出错。我在问题中提到,如果两个模板函数单独存在,它们可以编译时不会出错,但是当它们放在我上面的代码中时会出错。你完全正确:这很奇怪。我完全错过了事实上,您使用的是
std::result\u of_t
(而不是
std::result\u of
),这意味着您已经在使用c++14。那么我不确定为什么您的编译器会被这个模板专门化所阻塞。它可以与其他编译器一起工作(clang和gcc-我没有访问最近的MSVC的权限)。
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1469): error C2672: 'std::invoke': no matching overloaded function found
1>  c:\projects_svn\ssrcontrol_svn\testtemplate1\testtemplate1\testtemplate1.cpp(31): note: see reference to class template instantiation 'std::result_of<int (int &&)>' being compiled
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1469): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1469): note: With the following template arguments:
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1469): note: '_Callable=std::ios_base::iostate'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1469): note: '_Types={int}'