【问题标题】:C++ Pass parameter types with member pointer to templateC++ 使用成员指针传递参数类型到模板
【发布时间】:2021-02-23 08:16:34
【问题描述】:

我正在尝试将 SomeStruct 的成员转换为非 const void(*)() 的成员。为此,我使用了一个名为 Base 的类,它有一个模板成员函数 nc(),它通过转换自身将成员指针转换为非常量指针:(static_cast<Derived *>(this)->*ptr)()

问题:我还需要它来处理voids 接收参数(参见main() 的第二行)。我是参数打包/解包和转发的新手,因此将不胜感激!

这是我目前的代码(更新为更简单的示例):

#include <utility>
#include <iostream>

template <typename Derived> 
struct Base
{
    template <void (Derived::*ptr)() const>     // should also take arbitrary amount
    void nc()                                   // of params
    {
        (static_cast<Derived *>(this)->*ptr)();
    }
};

struct SomeStruct: public Base<SomeStruct>
{
    void exit() const;
    void takesParam(int num);
};

inline void SomeStruct::exit() const               
{
}

inline void SomeStruct::takesParam(int num)
{
}

int main()
{
    auto ptr1 = &Base<SomeStruct>::nc<&SomeStruct::exit>;    // works
    //auto ptr2 = &Base<SomeStruct>::nc<&SomeStruct::takesParam>; // error
}

以及使用g++-10 编译时收到的错误消息(未使用的变量可以忽略ofc):

main.cc: In function ‘int main()’:
main.cc:31:36: error: unable to deduce ‘auto’ from ‘& nc<&SomeStruct::takesParam>’
   31 |     auto ptr2 = &Base<SomeStruct>::nc<&SomeStruct::takesParam>;
      |                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cc:31:36: note:   couldn’t deduce template parameter ‘auto’
main.cc:30:10: warning: unused variable ‘ptr1’ [-Wunused-variable]
   30 |     auto ptr1 = &Base<SomeStruct>::nc<&SomeStruct::exit>;    // works
      |          ^~~~

【问题讨论】:

  • @newbie 它是对成员函数的数组的定义,而不是成员函数。因此,您只需要在数组元素之间写一个逗号。
  • 那你为什么把它写成一个函数呢? &amp;CPU::takesParam 的类型也不同于 &amp;CPU::exit。其中一个没有参数作为函数inline void CPU::exit() const,另一个有一个int 作为函数的参数inline void CPU::takesParam(int num)
  • @newbie - OP 没有“把它写成一个函数”。他们使用 C++ 的详细声明符语法定义了一个函数指针数组。至于你提到的所有其他内容......这就是问题的要点!
  • 不仅它们不能在同一个数组中,而且nc本身也被定义为template &lt;void (Derived::*ptr)() const&gt; void nc();,这意味着它的模板参数&lt;void (Derived::*ptr)() const&gt;应该只是一个没有参数的成员函数
  • @newbie 查看 StoryTeller 的评论。这确实是我正在寻找的;模板应采用带参数和不带参数的 void 函数指针。

标签: c++ templates function-pointers variadic-templates


【解决方案1】:

我不确定您要达到的目标,但因为在 nc 的定义中您有:

    template <void (Derived::*ptr)() const>
    void nc();

你不能引用 nc 不同类型的成员函数,应该像 void (Derived::*ptr)() const。 但是您只需添加另一个重载,例如:

    template <void (Derived::*ptr)(int)>
    void nc();

然后解决您的问题,然后您可以同时拥有:

void (CPU::*CPU::s_opcode[])() =
{
    &Base<CPU>::nc<&CPU::exit>,       // accepting const works
    &Base<CPU>::nc<&CPU::takesParam>  // does not work
};

你可以像这样定义 this 重载:

template <typename Derived>
template <void (Derived::*ptr)(int) >
void Base<Derived>::nc()                
{                                       
    (static_cast<Derived *>(this)->*ptr)(0);
}

【讨论】:

  • 非常感谢您的回答!这是一种可能,但不幸的是,我需要获得一个具有任意数量参数的成员指针。我改变了我的例子,省略了数组,也许这会清除一些东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多