[英]Parametrize template by function name c++11
具有以下功能
void print(int a) { cout << a << endl; }
void print(std::string a) { cout << a << endl; }
您可以执行以下模板
template <class T> void printT(T a) { print(a); }
是否有一些参数化函数名称的机制? 像这样:
template <class T, class F> void anyT(T a) { F(a); }
我不需要成为功能模板,只需采用某种机制即可实现相同功能。
您可以将函数作为参数传递。
template <class T, class F>
void anyT(T a, F f) {
f(a);
}
与传递101010建议的具有模板化参数类型的函数指针相比,此方法的优点在于,它可以与函数指针以及函子(实现lambda的任意类型的实例operator()
。
缺点是,在自由模板化参数的上下文中,获取重载函数的函数指针可能很棘手。 您需要使用
void (*f)(int) = print;
anyT(a, f);
或者,按照GuyGreer的建议,将其包装在lambda中。
我个人会使用101010的解决方案,但是您似乎不想将函数指针作为函数参数传递,而只是作为模板参数传递。 这是您可以执行的操作:
#include <string>
template <class T, void(*func)(T)>
void anyT(T t)
{
func(t);
}
void print(int i){}
void print(std::string s){}
int main()
{
anyT<int, print>(1);
anyT<std::string, print>("hello");
}
不幸的是,这意味着您每次都必须为函数指定模板参数,这很麻烦。
我认为更好的解决方案是仅使用通用模板参数和lambda:
template <class T, class F>
void anyT(T t, F f)
{
f(t);
}
auto printT = [](auto i){print(i);}
anyT(0, printT);
lambda是必需的,因为直接传递print
会很模棱两可,编译器不会知道您的意思是print(int)
还是print(std::string)
。
这是一个有用的宏:
#define OVERRIDES_OF(...) [](auto&&...args)->decltype(auto){ return __VA_ARGS__ (decltype(args)(args)...);}
结果是无状态lambda,该lambda转发到所提供的令牌。
使用:
static const auto printT = OVERRIDES_OF(print);
现在printT
是一个包装所有print
覆盖的对象。
努力理解这里的原理。 在c ++ 14中,我们有带有自动参数的lambda。 这会解决吗?
#include <iostream>
int main() {
int a = 1;
std::string str = "string";
auto print = [] (const auto& a) { std::cout << a << std::endl; };
print(a);
print(str);
}
您可以使用函数指针传递函数:
template <class T> void anyT(T a, void(*F)(T)) { F(a); }
但是您不能通过lambda:
auto printStr = [](std::string a) { cout << a << endl; };
anyT(foo, printStr); // This won't compile
另一种方法是使用std::function
:
template <class T>
void anyT(T a, std::function<void(T)> F) { F(a); }
或通用模板参数:
template <class T, class F>
void anyT(T a, F func) { func(t); }
这样做的缺点是无法解析重载的函数,但是可以使用辅助函数:
template<typename F>
std::function<F> make_function(F *funPtr) {
return std::function<F>(static_cast<F*>(funPtr));
}
并这样调用anyT
:
string foo = "foo";
anyT(foo, make_function<void(std::string)>(&print));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.