C++ 指向可变函数模板的指针
我有一个简单的类C++ 指向可变函数模板的指针,c++,templates,c++11,function-pointers,variadic-templates,C++,Templates,C++11,Function Pointers,Variadic Templates,我有一个简单的类a,提供了一个可变函数模板。此函数使用A中的私有数据,但函数本身是公共的。课程内容如下: class A { public: A() : _bla("bla: ") { } template <class T> void bar(const T& value) { std::cout << _bla << value << std::endl; }
a
,提供了一个可变函数模板。此函数使用A
中的私有数据,但函数本身是公共的。课程内容如下:
class A {
public:
A() :
_bla("bla: ") {
}
template <class T>
void bar(const T& value) {
std::cout << _bla << value << std::endl;
}
template <class H, class... T>
void bar(const H& value, const T&... data) {
std::cout << _bla << value << std::endl;
bar(data...);
}
private:
const std::string _bla;
};
template<typename F>
inline void foo(A& a, F f) {
unsigned int x(0), y(0), z(0);
f(a, x, y, z);
}
template<typename F>
inline void foo(F f) {
unsigned int x(0), y(0), z(0);
f(x, y, z);
}
int main()
{
A a;
a.bar(1, "two", 3, 4);
foo(bar_caller(a));
}
我不太确定从哪里开始,但我已经尝试了下面的方法——这是行不通的。我如何才能正确地执行此操作:
template <typename... T>
inline void foo(void (bar *)(const T&...)) {
unsigned int x(0), y(0), z(0);
bar(x, y, z);
}
但是也可以使用绑定到某些参数的a.bar
调用foo
,例如:
foo(&(a.bar(p1, p2));
我可以简单地将p1
和p2
添加到foo
定义本身,如:
foo(p1, p2, &a.bar);
但是,如果我能在前面添加这些参数,从语义上讲,这会更符合我的目的。在不实例化函数模板的情况下,无法传递函数模板的地址,因为它被视为一个完整的重载集(无论模板是否可变)。但是,您可以将其包装在泛型函子中:
struct bar_caller
{
template<typename... Ts>
void operator () (A& a, Ts&&... args)
{
a.bar(std::forward<Ts>(args)...);
}
};
因此,main()
中的函数调用将变成:
int main()
{
A a;
a.bar(1, "two", 3, 4);
foo(a, bar_caller());
}
不幸的是,在C++中,没有一个方法可以在函数中轻松地装入过载集而不需要定义一个单独的类——如上面的代码< BARAL Calor > 编辑:
如果您不想将A
对象直接传递给foo()
,您仍然可以让bar\u调用者
封装对A
对象的引用,在该对象上必须调用函数bar()
(只需注意对象的生存期,这样就不会使该引用悬空):
如果混乱,为什么要启用_?您可以将其重载为
void bar(){}
。顺便说一下,如果参数包是空的,则无需使用enable\u。只需为(H,T…)
设置一个模板重载,并设置一个不带任何参数的重载。foo
接受函数,但a.bar
不是函数。它是一个模板。模板没有地址。有a.bar
,a.bar
等功能;您希望传递给foo
的是哪一个?另外,您如何区分a.bar(p1,p2)
作为绑定到某些参数的函数和a.bar(p1,p2)
作为完全应用到所有参数的函数?+1 Andy,非常感谢您的回答!在实际情况中,我有一个扩展了其他类的类,它包括a
,在我的程序中是一个较小的类。如果我进入#将我的外部类包含在A
中,它实际上包含在外部类中-,我想我已经有的混乱会变成史诗般的意大利面^^^我真的不介意额外的参数,我可以将它们添加到foo
定义中,但是我真的不想把A
——我的外门课——传给foo
。有什么可能的解决方法吗?Andy,实际上我有A
作为外部函数,而bar
是一个可以从继承中获得的函数。到目前为止,我一直将变量作为引用传递给foo
,这样foo
将填充变量,我将使用从foo
检索到的值调用A
本身中的bar
。我只是加了一点背景,让它更清楚。我正在检查你的编辑。完美的解决方案!我想我现在能做我想做的事了!最后一个问题是,void operator()(Ts&&…args{}
)中的双重引用的确切含义是什么?@Rubens:很高兴它有帮助:)这是一个所谓的通用引用(这是Scott Meyers发明的一个非标准术语,您可能需要查找),它主要用于完美的转发。基本上,通用引用可以绑定左值和右值-事实上,这是一个右值引用,由于引用崩溃规则,它可以“变成”左值引用
int main()
{
A a;
a.bar(1, "two", 3, 4);
foo(a, bar_caller());
}
struct bar_caller
{
bar_caller(A& a_) : a(a_) { }
template<typename... Ts>
void operator () (Ts&&... args)
{
a.bar(std::forward<Ts>(args)...);
}
A& a;
};
template<typename F>
inline void foo(F f) {
unsigned int x(0), y(0), z(0);
f(x, y, z);
}
int main()
{
A a;
a.bar(1, "two", 3, 4);
foo(bar_caller(a));
}