VC2017 错误匹配模板类参数
VC2017 error matching template class parameter
>我在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 studio2017professionalvctoolsmsvc14.11.25503includeutility(486): error C2338: tuple index out of bounds
1>c:program files (x86)microsoft visual studio2017professionalvctoolsmsvc14.11.25503includefunctional(887): note: see reference to class template instantiation 'std::tuple_element<0,std::tuple<>>' being compiled
1>c:program files (x86)microsoft visual studio2017professionalvctoolsmsvc14.11.25503includetuple(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:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.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:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.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:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.cpp(41): error C2672: 'FSM::All': no matching overloaded function found
1>c:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.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:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.cpp(41): note: With the following template arguments:
1>c:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.cpp(41): note: 'CALLABLE=std::_Binder<std::_Unforced,bool (__thiscall SFF::* )(FSPtr),SFF *,const std::_Ph<1> &>'
1>c:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.cpp(41): note: 'ARGS={}'
1>c:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.cpp(49): error C2672: 'FSM::All': no matching overloaded function found
1>c:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.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:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.cpp(49): note: With the following template arguments:
1>c:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.cpp(49): note: 'CALLABLE=std::_Binder<std::_Unforced,bool (__thiscall SFF::* )(FSPtr,int),SFF *,const std::_Ph<1> &,const std::_Ph<2> &>'
1>c:userss.chansourcereposconsoleapplication1consoleapplication1consoleapplication1.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();
<</div>
div class="answers"> 代码无法编译的原因如下:
bool Do()
{
return m_pFsm->All(std::bind(&SFF::VF, this, std::placeholders::_1));
}
在这里,您使用包装函数All
来调用 VF 函数。但:1(All
函数应该获取函数参数:
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;
}
Args
这里应该代表FSPtr
类型的单个参数,请参阅 SFF::VF
的签名。
所以正确的代码应该是:
return m_pFsm->All(std::bind(&SFF::VF, this, std::placeholders::_1), somethingOfFSPtrType);
相关文章:
- C++声明模板参数阴影模板参数错误
- 为什么 CRTP 模板C++给出无效参数错误?
- (C/C++)fscanf_s从txt文件以字符形式读取数组时缺少整数参数错误
- 参数错误可能与类型不匹配有关?
- printf 和 strftime 的参数错误无效
- 如何修复"ctypes"。参数错误:参数 2:<键入"异常.类型错误">:RaspberryPi 中的错误类型"错误
- 如何修复"没有重载函数需要 2 个参数"错误C++
- 术语不计算为函数采用 1 个参数错误?
- 从带有 getline() 的文件读入一行上有多个信息得到无效参数错误
- 为什么我不能像使用 std::string::size_type 那样使用 QList::size_type?(模板参数错误)
- cudaFreeHost() 无效参数错误
- 精神语法不会编译:函数模板参数错误?
- C 功能具有参考参数错误的迭代器错误.寻求解释
- 使用getDefaultCommConfig使用无效的参数错误
- C++ 可变参数模板和模板模板参数:错误:模板参数列表中参数 1 处的类型/值不匹配
- 使用SWIG生成的Python库时,向量分配器参数错误
- 错误C2664:无法转换参数错误
- C 作为参数错误的功能
- 命令行参数错误
- 增强Python参数错误