#include <iostream>
void padd(int a, int b) { std::cout << a + b << std::endl; }
void psub(int a, int b) { std::cout << a - b << std::endl; }
template <??? op>
class Foo {
public:
template<typename... Arguments>
void execute(Arguments... args) {
op(args ...);
}
};
int main() {
auto f1 = Foo<padd>();
f1.execute(5, 6); // ideally would print 11
auto f2 = Foo<psub>();
f2.execute(5, 6); // ideally would print -1
return 0;
}
我试图弄清楚如何在C ++中将函数(以及,如果可能的话,模板函数)绑定为模板参数。
目前我不知道这是否可能。
这里的一个踢球者是功能签名不保证是相似的。
编辑:感谢@sehe和@Potatoswatter,我当前的解决方案就是:http://ideone.com/0jcbUi。会在适当的时候写出答案。
答案 0 :(得分:6)
我建议让编译器担心在适当的时候解析函数签名。 http://ideone.com/ZeLt1E(代码包含在下方)。
如果你需要调整重载集或多态接口,我建议你也看一下BOOST_PHOENIX_ADAPT_FUNCTION。
编辑回复评论:这是一个演示如何直接使用功能指针和/或指针到成员函数作为函数参数的演示。这是另一种极端方法: http://ideone.com/120Ezs
#include <iostream>
template <typename F>
struct Foo {
Foo(F&& f) : f(std::forward<F>(f)) {}
template<typename... Arguments>
void execute(Arguments... args) {
f(args ...);
}
private:
F f;
};
template <typename F>
Foo<F> make_foo(F&& f = F()) { return {f}; }
void padd(int a, int b) { std::cout << a + b << std::endl; }
void psub(int a, int b) { std::cout << a - b << std::endl; }
int main() {
auto f = make_foo(padd);
f.execute(5, 6);
make_foo(psub).execute(5, 6);
return 0;
}
答案 1 :(得分:3)
只是观察您没有或想要运行时状态。部分来自您在C ++聊天室中的评论的推断。
功能没有唯一类型。如果你想生成一个捕获应该调用函数的唯一类型,请使用类模板来执行此操作。
template< typename t, t v >
struct constant {
typedef t type;
static constexpr t value = v;
operator t () { return v; }
};
这与std::integral_constant
基本相同,但会从名称中删除integral
以避免混淆。 (实际上我只使用std::integral_constant
进行了测试,如果你想变得更干净,那取决于你。)
现在,您可以为函数提供单独的类型,这些类型是无状态的,默认构造的函子。
typedef constant< decltype( & padd ), padd > padd_type;
typedef constant< decltype( & psub ), psub > psub_type;
padd_type()( 2, 3 ); // prints 5
请注意,无状态lambdas可转换为函数指针并与此类系统兼容,但您需要明确指定函数指针类型。仅decltype
不会让你到那里。
答案 2 :(得分:0)
感谢Potatoswatter和他在C ++休息室的帮助,在这里,我已经为我的问题制定了解决方案。
#include <iostream>
#include <functional>
template <typename func_t, func_t func>
struct Foo {
template <typename... Arguments>
void execute(Arguments... args) {
func(args ...);
}
};
template <typename T, typename func_t, func_t func>
struct FooMember {
T member;
FooMember(T member) : member(member) {}
template <typename... Arguments>
void execute(Arguments... args) {
std::function<void(T&, Arguments ...)> f(func);
f(this->member, args ...);
}
};
struct Bar {
int z;
Bar(int z) : z(z) {}
void add(int x, int y) { std::cout << x + y + z << std::endl; }
};
void padd(int x, int y, int z) { std::cout << x + y + z << std::endl; }
int main() {
auto a = Foo<decltype(&padd), &padd>();
auto b = FooMember<Bar, decltype(&Bar::add), &Bar::add>(Bar(2));
a.execute(4, 5, 6); // prints 4+5+6 : 15
b.execute(4, 5); // prints 4+5+a.z : 4+5+2 : 11
return 0;
}