确定模板函子C++参数数
Determining number of arguments of C++ template functor
假设我们有:
template<typename F, typename T1, typename T2>
void my_magic_method(F func, T1 t1, T2 t2)
{
if (???)
func(t1);
else
func(t1,t2);
}
什么可以帮助我确定:
参数数
也许每个参数的类型
返回值的类型
由于 MSVS 2010,我无法使用可变参数模板...
更新
我的第一个解决方案:
template<typename F>
auto my_magic_func(F f) -> decltype(f(1))
{
return f(1);
}
template<typename F>
auto my_magic_func(F f, void * fake = NULL) -> decltype(f(2,3))
{
return f(2,3);
}
int main()
{
auto x1 = my_magic_func([](int a){ return a+100; });
auto x2 = my_magic_func([](int a, int b){ return a*b; });
// x1 == 1+100
// x2 == 2*3
}
这就是我的函数类型重载方式。它有效,但也许是更好的解决方案?
不完全是你要求的,但如果我正确理解你的意图,在VC++ 2010中,通过基于arity的简单重载是可能的(但丑陋的):
#include <utility>
#include <string>
#include <iostream>
template<typename F, typename T1>
auto my_magic_method(F&& func, T1&& t1) ->
decltype(std::forward<F>(func)(std::forward<T1>(t1)))
{
return std::forward<F>(func)(std::forward<T1>(t1));
}
template<typename F, typename T1, typename T2>
auto my_magic_method(F&& func, T1&& t1, T2&& t2) ->
decltype(std::forward<F>(func)(std::forward<T1>(t1), std::forward<T2>(t2)))
{
return std::forward<F>(func)(std::forward<T1>(t1), std::forward<T2>(t2));
}
struct string_to_float_functor
{
float operator ()(std::string const& s) const
{
return std::stof(s);
}
};
int main()
{
auto a = my_magic_method([](std::string const& x) { return x + x; }, "foo");
auto b = my_magic_method([](double x, int y) { return x * y; }, 21.5, 3);
auto c = my_magic_method(string_to_float_functor(), "3.14159265");
std::cout << a << 'n' << b << 'n' << c << 'n';
}
这支持一元和二进制函子 – 继续该模式并根据需要为其他参数添加重载。
这里有几种方法;都假设C++11。在 clang++ 3.2 上使用 -std=c++11 进行测试。
//Taking a function pointer argument (template types inferred)
template <typename ret, typename ... Args>
constexpr int arg_count(ret (*f)(Args...)) {
return sizeof...(Args);
}
//Taking a function type (or related) directly
template <typename T>
struct ArgCount {
static const int value = 0;
};
template <typename Ret, typename ... Args>
struct ArgCount<Ret(Args...)> {
static const int value = sizeof...(Args);
};
template <typename Ret, typename ... Args>
struct ArgCount<Ret(*)(Args...)> {
static const int value = sizeof...(Args);
};
template <typename Ret, typename ... Args>
struct ArgCount<Ret(&)(Args...)> {
static const int value = sizeof...(Args);
};
//Using the latter for dispatch
template <int N>
struct helper {
template<typename F, typename T1, typename T2>
static void call(F func, T1 t1, T2 t2);
};
template <>
struct helper<1> {
template<typename F, typename T1, typename T2>
static void call(F func, T1 t1, T2 t2) {
func(t1);
}
};
template <>
struct helper<2> {
template<typename F, typename T1, typename T2>
static void call(F func, T1 t1, T2 t2) {
func(t1, t2);
}
};
template<typename F, typename T1, typename T2>
void my_magic_method(F func, T1 t1, T2 t2)
{
helper<ArgCount<F>::value>::call(func, t1, t2);
}
//Testing
#include <cstdio>
void a(int a, int b) { printf("%in", a + b); }
void b(int x) { printf("%in", x); }
int main() {
printf("%i %in", arg_count(a), arg_count(b));
printf("%i %in", ArgCount<decltype(a)>::value, ArgCount<decltype(b)>::value);
my_magic_method(a, 1, 2);
my_magic_method(b, 1, 2);
}
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- 没有名称的C++模板参数
- 如何将enable-if与模板参数和参数包一起使用