Call member method of a variadic class template with a member field
我了解了一些变量模板,并在互联网上搜索了一些示例,现在尝试编写一些复杂的代码,将成员称为变量类模板的方法及其字段之一。我不明白为什么它不起作用。请帮忙。
以下是示例类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | class BarBase { public: BarBase() = default; virtual void call() = 0; }; template<typename O, typename M, typename... A> class Bar : public BarBase { public: Bar(O* o, M m, A&&... a) : BarBase() , m_o(o), m_m(m), m_a(std::forward<A>(a)...) { } void call() override final { callInnerWithArgsInside(); } private: void callInnerWithArgsInside() { (m_o->*m_m)(m_a); // Some errors happends here } O* m_o; M m_m; std::tuple<typename std::remove_reference<A>::type...> m_a; }; template<typename O, typename M, typename... A> BarBase* crateBar(O* o, M m, A&&... a) { return new Bar<O, M, A...>(o, m, std::forward<A>(a)...); } |
从主电话:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | struct Foo { void foo(int ii, float ff, std::string ss) { std::cout <<"called" << std::endl; } }; int main() { Foo f; int i = 10; float ff = 20.2f; std::string s ="Hello"; BarBase* bar = crateBar(&f, &Foo::foo, i, ff, s); bar->call(); } |
错误:
主CPP
1>d:drafts estmain.cpp(203):错误C2198:'void(uu thiscall foo::*)(int,float,std::string)':调用的参数太少
1>d:draftsmain.cpp(202):编译类模板成员函数"void bar::callinnerwithargsinside(void)"时
1>与
1 >
1>o=foo
1>,m=void(uu thiscall foo::*)(int,float,std::string)
1>
1>d:drafts eu testsmain.cpp(197):请参阅函数模板实例化的引用"void bar::callinnerwithargsinside(void)"正在编译
1>与
1 >
1>o=foo
1>,m=void(uu thiscall foo::*)(int,float,std::string)
1>
1>d:drafts eu testsmain.cpp(214):请参见对正在编译的类模板实例化"bar"的引用
1>与
1 >
1>o=foo
1>,m=void(uu thiscall foo::*)(int,float,std::string)
1>
1>d:drafts eu testsmain.cpp(225):请参阅正在编译的函数模板实例化'barbase*板条箱(o*,m,int&;,float&;,std::string&;)'
1>与
1 >
1>o=foo
1>,m=void(uu thiscall foo::*)(int,float,std::string)
1>
=====生成:0成功,1失败,0最新,0跳过===========
您正在将元组传递给函数,而不是单个类型参数。以下将向调用传递所需的类型参数:
1 2 3 4 5 6 7 8 9 10 | template<std::size_t... I> void callInnerWithArgsInside2(std::index_sequence<I...>) { (m_o->*m_m)(std::get(m_a)...); } void callInnerWithArgsInside() { return callInnerWithArgsInside2( std::make_index_sequence<sizeof...(A)>()); } |
现场演示
Eddi1: C++ 11版本
我已经实现了C++ 11版本,请参阅更新的实况演示