c++ - VC2017错误匹配模板类参数

标签 c++ templates visual-studio-2017

我在 VS2013 中使用了一个 C++ 模板函数,没有任何问题。但是当我升级到 VS2017 时,VC 编译器提示它无法匹配参数列表。任何人都可以帮助我如何修复代码?

一个简化的代码片段在这里演示了这个问题:

#include "stdafx.h"
#include <functional>
#include <memory>

class FS
{
};

typedef std::shared_ptr<FS> FSPtr;

class FSM
{
public:
    FSM() : m_pFs(new FS()) {}

    template <typename CALLABLE, typename... ARGS>
    typename std::enable_if<std::is_same<bool, std::result_of_t<CALLABLE(ARGS&&...)>>::value, std::result_of_t<CALLABLE(ARGS&&...)>>::type
        All(CALLABLE fn, ARGS&&... args) const        // line 21
    {
        std::function<bool()> rFunc = std::bind(fn, m_pFs, args...);
        bool bSuccess = rFunc();
        return bSuccess;
    }
private:
    FSPtr m_pFs;
};

class SFF
{
public:
    SFF() : m_pFsm(new FSM()) {}
    bool VF(FSPtr pFs)
    {
        return nullptr != pFs;
    }
    bool Do()
    {
        return m_pFsm->All(std::bind(&SFF::VF, this, std::placeholders::_1));        // line 41
    }

    bool TF(FSPtr pFs, int n)
    {
        return nullptr != pFs && 0 != n;
    }
    bool Do1(int n)
    {
        return m_pFsm->All(std::bind(&SFF::TF, this, std::placeholders::_1, std::placeholders::_2), n);        // line 49
    }

private:
    std::shared_ptr<FSM> m_pFsm;
};


int _tmain(int argc, _TCHAR* argv[])
{
    SFF oSff;

    bool bOk1 = oSff.Do();
    bool bOk2 = oSff.Do1(4);
    int rc =  (bOk1 && bOk2) ? 0 : 1;

    return rc;
}

VS2017 VC编译器输出的错误是:
1>------ Build started: Project: ConsoleApplication1, Configuration: Debug Win32 ------
1>ConsoleApplication1.cpp
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.11.25503\include\utility(486): error C2338: tuple index out of bounds
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.11.25503\include\functional(887): note: see reference to class template instantiation 'std::tuple_element<0,std::tuple<>>' being compiled
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.11.25503\include\tuple(793): note: see reference to function template instantiation 'const tuple_element<_Index,_Tuple>::type &&std::get(const std::tuple<_Rest...> &&) noexcept' being compiled
1>        with
1>        [
1>            _Tuple=std::tuple<_Rest...>
1>        ]
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(41): note: see reference to class template instantiation 'std::result_of<std::_Binder<std::_Unforced,bool (__thiscall SFF::* )(FSPtr),SFF *,const std::_Ph<1> &> (void)>' being compiled
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(21): note: while compiling class template member function 'std::enable_if<std::is_same<bool,result_of<_Ty>::type>::value,result_of<_Ty>::type>::type FSM::All(CALLABLE,ARGS &&...) const'
1>        with
1>        [
1>            _Ty=CALLABLE (ARGS &&...)
1>        ]
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(41): error C2672: 'FSM::All': no matching overloaded function found
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(41): error C2893: Failed to specialize function template 'std::enable_if<std::is_same<bool,result_of<_Ty>::type>::value,result_of<_Ty>::type>::type FSM::All(CALLABLE,ARGS &&...) const'
1>        with
1>        [
1>            _Ty=CALLABLE (ARGS &&...)
1>        ]
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(41): note: With the following template arguments:
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(41): note: 'CALLABLE=std::_Binder<std::_Unforced,bool (__thiscall SFF::* )(FSPtr),SFF *,const std::_Ph<1> &>'
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(41): note: 'ARGS={}'
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(49): error C2672: 'FSM::All': no matching overloaded function found
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(49): error C2893: Failed to specialize function template 'std::enable_if<std::is_same<bool,result_of<_Ty>::type>::value,result_of<_Ty>::type>::type FSM::All(CALLABLE,ARGS &&...) const'
1>        with
1>        [
1>            _Ty=CALLABLE (ARGS &&...)
1>        ]
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(49): note: With the following template arguments:
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(49): note: 'CALLABLE=std::_Binder<std::_Unforced,bool (__thiscall SFF::* )(FSPtr,int),SFF *,const std::_Ph<1> &,const std::_Ph<2> &>'
1>c:\users\s.chan\source\repos\consoleapplication1\consoleapplication1\consoleapplication1.cpp(49): note: 'ARGS={int &}'
1>Done building project "ConsoleApplication1.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

任何帮助深表感谢。

最佳答案

显然 fn ( CALLABLE ) 在 FSM::All()应该被称为 fn(m_pFs, args...) ,而不是 fn(args...)
所以你的 SFINAE 是错误的:

  • std::result_of_t<CALLABLE(ARGS&&...)>缺少 m_pFs论据:
  • std::result_of_t<CALLABLE(FSPtr, ARGS&&...)>

  • 如果添加 FSPtr它应该工作。但请记住 result_of已弃用。您可以简单地使用尾随返回类型来实现相同的效果:
    template <typename CALLABLE, typename... ARGS>
    auto All(CALLABLE fn, ARGS&&... args)
        -> std::enable_if_t<std::is_same_v<bool, decltype(fn(std::declval<FSPtr>(), args...))>, bool>
    {
    

    另请注意 std::bind返回一个 lambda。创建 std::function从那将是低效的。最好按原样使用返回的类型:
        auto rFunc = std::bind(fn, m_pFs, args...); // no need to cast to std::function
        rFunc();
    

    关于c++ - VC2017错误匹配模板类参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55605596/

    相关文章:

    c++ - 根据模板参数选择构造器

    JavaScript 异常不会从 chrome 返回到 Visual Studio 2017

    c++ - C语言打印时如何对浮点类型变量进行舍入?

    C++ - 从基类运算符内部调用基类重写的虚方法

    c++ - 在继承类 C++ 中重载 >>

    c++ - MySQL 连接器/C++ 无法在 CodeBlocks 中工作

    javascript - 带液体火焰的 Ember 加载模板

    c++ - `invalid initialization of non-const reference` 是什么意思?

    git - 为什么 "Compare with Unmodified"在 Visual Studio 2017 中不起作用?

    c# - 创建新标准 .NET 项目时的依赖项警告