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