C++ 使用成员字段调用变量类模板的成员方法

C++ 使用成员字段调用变量类模板的成员方法,c++,c++11,variadic-templates,C++,C++11,Variadic Templates,我学习了一些关于可变模板的知识,并在互联网上搜索了一些示例,现在我试图编写一些复杂的代码,用可变类模板的一个字段调用成员方法。我不明白为什么它不起作用。请帮忙 以下是示例类: class BarBase { public: BarBase() = default; virtual void call() = 0; }; template<typename O, typename M, typename... A> class Bar : public Ba

我学习了一些关于可变模板的知识,并在互联网上搜索了一些示例,现在我试图编写一些复杂的代码,用可变类模板的一个字段调用成员方法。我不明白为什么它不起作用。请帮忙

以下是示例类:

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)...);
}
class巴巴多斯
{
公众:
巴巴多斯()=默认值;
虚空调用()=0;
};
模板
分类栏
:巴巴多斯公国
{
公众:
酒吧(O*O,M,A&…A)
:巴巴多斯()
,m_o(o),m_m(m),m_a(std::forward(a)…)
{ }
void call()覆盖final
{
callInnerWithArgsInside();
}
私人:
无效callInnerWithArgsInside()
{
(m_o->*m_m)(m_a);//这里发生了一些错误
}
O*m_O;
嗯,嗯,;
std::元组m_a;
};
模板
巴巴多斯*板条箱(O*O、M、A和A)
{
返回新条(o、m、std::forward(a)…);
}
和来自main的电话:

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();
}
structfoo
{
void foo(整数ii、浮点ff、标准::字符串ss)
{
std::cout d:\drafts\u tests\main.cpp(203):错误C2198:'void(\uu thiscall Foo::*)(int,float,std::string)':调用的参数太少

1> d:\drafts\u tests\main.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\u tests\main.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\u tests\main.cpp(214):请参阅对正在编译的类模板实例化“Bar”的引用

1> 与

1>[

1> O=Foo

1> ,M=void(uu thiscall Foo::*)(int,float,std::string)

1> ]

1> d:\drafts\u tests\main.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跳过========

您正在向函数传递元组,而不是单个类型参数。以下操作将向调用传递所需的类型参数:

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)>());
}
模板
无效callInnerWithArgsInside2(标准::索引顺序)
{
(m_o->*m_m)(标准::获取(m_a)…);
}
无效callInnerWithArgsInside()
{
返回callInnerWithArgsInside2(std::make_index_sequence());
}


EDIT1:C++11版本


我已经实现了一个C++11版本,请参见

它到底是如何工作的?我想你会发现一个有趣的读物。它是C++11的“std::index_sequence”、“std::make_index_sequence”吗?抱歉,你是对的,这是C++14,但我以前为C++11实现了index_seq,请参见更新的演示