【发布时间】:2020-07-08 21:46:50
【问题描述】:
是否可以像下面这样在 C++14 中编写模板函数
这里是示例https://godbolt.org/z/9gRk-t
// pseudo code
#include <type_traits>
template <typename T, typename R, typename... Args>
decltype(auto) Call(T& obj, R(T::*mf)(Args...), Args&&... args)
{
return (obj.*mf)(std::forward<Args>(args)...);
}
所以,对于一个测试类
struct Test
{
int Func(){return 1;};
bool Func(bool){return true;}; // overload
void FuncInt(int){};
};
模板可以为下面的用例工作(但失败了)
int main()
{
Test test;
// for overload case
auto a = Call<int()>(test, &Test::Func);
auto b = Call<bool(bool)>(test, &Test::Func, true);
// for non-overload case
Call(test, &Test::FuncInt, 1);
return 0;
}
这里是错误信息。
#1 with x64 msvc v19.24
example.cpp
<source>(23): error C2672: 'Call': no matching overloaded function found
<source>(23): error C2770: invalid explicit template argument(s) for 'decltype(auto) Call(T &,R (__cdecl T::* )(Args...),Args &&...)'
<source>(5): note: see declaration of 'Call'
<source>(24): error C2672: 'Call': no matching overloaded function found
<source>(24): error C2770: invalid explicit template argument(s) for 'decltype(auto) Call(T &,R (__cdecl T::* )(Args...),Args &&...)'
<source>(5): note: see declaration of 'Call'
Compiler returned: 2
【问题讨论】:
-
Test成员定义中的语法错误:方法定义后有多余的分号,return语句和结构的右大括号后缺少分号。 -
注意 C++17 中有std::invoke
-
@Jarod42 虽然不能直接将指向重载成员函数的指针传递给
std::invoke。 -
@aschepler:
std::invoke(static_cast<bool (Test::*)(bool)>(&Test::Func), test, true);或std::invoke([](Test& test, auto... args){ return test.Func(args...);}, test, true);。 -
@Jarod 这就是为什么我一定要“直接”输入;)
标签: c++ c++11 templates c++14 variadic-templates