如何将多个函数重载作为单个参数传递?
How can I pass multiple function overloads as a single argument?
这是试图摆脱宏的另一种情况。考虑
void f_(int i) { printf("f_(int)t%dn", i); }
void f_(int i, double x) { printf("f_(int, double)t%d, %5.3fn", i, x); }
void g_(int i) { printf("g_(int)t%dn", i); }
void g_(int i, double x) { printf("g_(int, double)t%d, %5.3fn", i, x); }
(想象一下,f_()
从.foo文件中获取数据或使用硬编码的"虚拟"值,g_()
.bar执行相同的操作。 可能有一个函数来决定调用哪个重载:
void f(int i, double d) { (i > 0) ? f_(i, d) : f_(i); }
与g_()
相同的逻辑重复:
void g(int i, double x) { (i > 0) ? g_(i, x) : g_(i); }
使用宏可以轻松删除重复的代码:
#define h(i, x, func_) (i > 0) ? func_(i, x) : func_(i);
// ...
h(-1, 314.1, f_);
h(99, 314.1, f_);
h(-1, 314.1, g_);
h(99, 314.1, g_);
但是,当然,我们宁愿不要在C++中使用宏。 "显而易见"的模板
template<typename T>
void h2(int i, double x, T t)
{
(i > 0) ? t(i, x) : t(i);
}
// ...
h2(-1, 314.1, f_);
失败,因为编译器无法确定要使用的f_()
重载。
如何替换宏h
的功能?
您可以使用可变参数 lambda 并让 lambda 调用您要调用的函数。
template<typename T>
void h2(int i, double x, T t)
{
i > 0 ? t(i, x) : t(i);
}
int main()
{
h2(-1, 314.1, [](auto... args){ f_(args...); });
// ^^ change this to g_ if you want to use g_ instead of f_
}
如果你不介意改变f_
和g_
的定义,你可以做类似的事情
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
auto f_ = overloaded(
[](int i) { printf("f_(int)t%dn", i); },
[](int i, double x) { printf("f_(int, double)t%d, %5.3fn", i, x); }
);
auto g_ = overloaded(
[](int i) { printf("g_(int)t%dn", i); },
[](int i, double x) { printf("g_(int, double)t%d, %5.3fn", i, x); }
);
那么你的h
模板正是你想要的
template<typename T>
void h(int i, double x, T t)
{
i > 0 ? t(i, x) : t(i);
}
overloaded
模板无耻地从此示例中复制std::visit
.
要使其适用于 C++11,您必须调整overloaded
模板并添加一个帮助程序函数来推断类型参数
template<class... Ts> struct overloads;
template<> struct overloads<>{};
template<class T, class... Ts> struct overloads<T, Ts...> : T, overloads<Ts...>
{
overloads(T t, Ts... ts) : T(t), overloads<Ts...>(ts...) {}
using T::operator();
};
template<class... Ts> overloads<Ts...> overloaded(Ts&&... ts)
{ return overloads<Ts...>(std::forward<Ts>(ts)...); }
您不能直接执行此操作,因为推断T
的类型需要包含参数类型,但您可以按照以下命令行执行一些操作
#include <iostream>
struct overloader {
void foo(int) { std::cout << "intn";}
void foo(double) { std::cout << "doublen";}
};
template <typename T>
void bar(int x,double y,bool opt, T t){
if (opt) { t.foo(x); }
else { t.foo(y); }
}
int main() {
overloader ol;
bar(1,1,true,ol);
bar(1,1,false,ol);
}
指纹:
国际
双
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用指向成员的指针将成员函数作为参数传递
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何将部分流作为参数传递
- 我正在开发服务器,ip作为参数传递不起作用
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 将参数传递为"const"的奇怪效果
- 如何在 c++ 中将函数作为参数传递?
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- 如何将多个函数重载作为单个参数传递?
- 如何在C++中使用单个模板参数传递两个 lambda 函数
- 将多个参数作为单个宏参数传递
- 如何在保留单个参数的同时传递可变参数列表
- 是否可以将指向类成员的指针作为C++中的单个参数传递
- 将单个变量作为std::initializer_list作为函数参数传递