首页 文章

使用成员字段调用可变参数类模板的成员方法

提问于
浏览
3

我学习了一些关于可变参数模板的知识,并在互联网上搜索了一些示例,现在尝试编写一些棘手的代码,用一个字段调用成员变量类模板的方法 . 我无法理解为什么它不起作用 . 请帮忙 .

以下是示例类:

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跳过==========

1 回答

  • 2

    您正在将元组传递给函数,而不是单个类型参数 . 以下内容将所需的类型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)>());
    }
    

    live demo

    EDIT1: C++11 version

    我已经实现了C 11版本,请参阅updated live demo

相关问题