提问人:Ariz 提问时间:11/4/2023 最后编辑:user12002570Ariz 更新时间:11/4/2023 访问量:69
如何将模板类放入args包本身?
How to put template class into args pack itself?
问:
我有如下模板类:
template<typename T>
class A;
template<typename ...Args>
class A<void(Args...)> {
public:
void(*callback)(Args....);
void foo(Args... args) {
/* stuffs */
}
};
是否可以在定义指定类时放入 Args 包本身,例如:?
使类类似于:A<void(Args...)>
A<void(A<...>, /* other args */)>
class B {
public:
void(*callback)(const B&, /* other args */);
void foo(const B&, /* other args */) {
/* stuffs */
}
};
我可以通过使用 like 来使其工作,然后转换回函数中的原始函数。只是想问一下是否可能以及如何去做,而不使用.void*
A<void(void*, /* other args */>
void*
答:
0赞
Pepijn Kramer
11/4/2023
#1
我会让 lambda/std::function 组合完成繁重的工作。 这可能会导致一些开销,但代码变得更易于维护,如下所示:
#include <functional>
#include <iostream>
#include <string>
#include <type_traits>
template<typename... args_t>
class A
{
public:
template<typename fn_t>
auto register_callback(fn_t fn) // possibly constrain here (using SFINAE or concept)
{
m_callback = fn;
}
void func_with_callback(args_t&&... args)
{
m_callback(std::forward<args_t>(args)...);
}
private:
std::function<void(const args_t&...)> m_callback;
};
int main()
{
std::string hello{"Hello"};
A<std::string> a;
// use lambdas to capture all the variables you need.
a.register_callback([=](const std::string& name){ std::cout << hello << " " << name; });
a.func_with_callback("Dave");
return 0;
}
评论
0赞
Ariz
11/4/2023
很抱歉让你对我的问题感到困惑,课堂上的字段只是一个例子,它可能会有所不同。但我需要的是模板中的列表必须与类字段中的列表相同,并且必须与列表中的列表相同,并且本身在列表中一次。Args
Args
Args
A<...>::foo()
A<...>
Arg
Args
0赞
Pepijn Kramer
11/4/2023
没问题;)我花了几分钟来写这个
0赞
user12002570
11/4/2023
#2
是否可以在定义指定类时放入 Args 包本身,例如:?
A<void(Args...)>
A<void(A<...>, /* other args */)>
是的,如下图所示。请注意 和 的定义中添加的第一个参数。const A<void(Args...)>&
callback
foo
template<typename T>
class A;
template<typename ...Args>
class A<void(Args...)> {
public:
//------------------vvvvvvvvvvvvvvvvvvvvv-------------->added this first argument
void(*callback)(const A<void(Args...)>&, Args...);
//-----------vvvvvvvvvvvvvvvvvvvvv--------------------->added this first argument
void foo(const A<void(Args...)>&,Args... args) {
}
};
void func(double, int)
{
}
int main()
{
A<decltype(func)> a;
}
以上将导致您想要的类类型的实例化:
template<>
class A<void (double, int)>
{
public:
void (*callback)(const A<void (double, int)> &, double, int);
inline void foo(const A<void (double, int)> &, double __args1, int __args2);
// inline A() noexcept = default;
};
请注意,使用注入的类名,只需在参数列表中写入即可使代码更具可读性。const A&
template<typename ...Args>
class A<void(Args...)> {
public:
//------------------------v---------------->injected class name
void(*callback)(const A&, Args...);
//----------------------------------------->injected class name
void foo(const A&,Args... args) {
}
};
评论
0赞
Ariz
11/4/2023
谢谢你的回答。我也明白了。因为可以用在问题以外的情况下一次,所以我需要的是模板中的列表必须与类字段中的列表相同,并且必须与中的列表相同。A<void(Args...)>
Args
Args
Args
A<...>::foo()
0赞
user12002570
11/4/2023
@Ariz 不清楚你在问什么/说什么。请随时为您提出一个新的单独问题,跟进问题和新要求。不应在问题已经有答案后添加新要求,以致使答案无效。
0赞
user12002570
11/4/2023
@Jarod42 啊,这将使代码更具可读性。更新。
评论