[英]Call member method of a variadic class template with a member field
我学习了一些关于可变参数模板的知识,并在互联网上搜索了一些样本,现在尝试编写一些棘手的代码来调用成员一个带有一个字段的可变类模板的方法。 我无法理解为什么它不起作用。 请帮忙。
以下是示例类:
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)...);
}
并从主要电话:
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();
}
错误:
main.cpp中
1> d:\\ drafts_tests \\ main.cpp(203):错误C2198:'void(__ thishisall Foo :: *)(int,float,std :: string)':调用的参数太少
1> d:\\ drafts_tests \\ main.cpp(202):在编译类模板成员函数时'void Bar :: callInnerWithArgsInside(void)'
1>用
1> [
1> O = Foo
1>,M = void(__ thiscall Foo :: *)(int,float,std :: string)
1>]
1> d:\\ drafts_tests \\ main.cpp(197):参见函数模板实例化'void Bar :: callInnerWithArgsInside(void)'被编译
1>用
1> [
1> O = Foo
1>,M = void(__ thiscall Foo :: *)(int,float,std :: string)
1>]
1> d:\\ drafts_tests \\ main.cpp(214):参见类模板实例化'Bar'正在编译
1>用
1> [
1> O = Foo
1>,M = void(__ thiscall Foo :: *)(int,float,std :: string)
1>]
1> d:\\ drafts_tests \\ main.cpp(225):参见函数模板实例化'BarBase * crateBar(O *,M,int&,float&,std :: string&)'被编译
1>用
1> [
1> O = Foo
1>,M = void(__ thiscall Foo :: *)(int,float,std :: string)
1>]
==========构建:0成功,1失败,0最新,0跳过==========
您将元组传递给函数,而不是单个类型参数。 以下内容将所需的类型args传递给调用:
template<std::size_t... I>
void callInnerWithArgsInside2(std::index_sequence<I...>)
{
(m_o->*m_m)(std::get<I>(m_a)...);
}
void callInnerWithArgsInside()
{
return callInnerWithArgsInside2( std::make_index_sequence<sizeof...(A)>());
}
EDIT1:C ++ 11版本
我已经实现了C ++ 11版本,请参阅更新的现场演示
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.