给出以下代码:
struct Window{
void show();
//stuff
}w1, w2, w3;
struct Widget{
void show();
//stuff
}w4, w5, w6;
struct Toolbar{
void show();
//stuff
}t1, t2, t3;
Run Code Online (Sandbox Code Playgroud)
我想要show一堆物品:
for (auto &obj : {w3, w4, w5, t1})
obj.show();
Run Code Online (Sandbox Code Playgroud)
然而,这不会编译,因为std::initializer_list<T>在for-loop中无法推断T,事实上并没有真正T适合的.我不想创建类型擦除类型,因为需要大量的代码和不必要的运行时开销.如何正确编写循环以便obj分别为概念列表中的每个项推导出类型?
Nik*_*iou 58
在现代C++中,您将使用折叠表达式来"遍历"应用成员函数的异构参数:
auto Printer = [](auto&&... args) {
(args.show(), ...);
};
Printer(w1, w2, w3, w4, w5, w6, t1, t2, t3);
Run Code Online (Sandbox Code Playgroud)
您可以在我的博客中阅读更多相关内容
Ric*_*ges 39
boost :: fusion很棒但是oldskool - 它迎合了c ++ 03中的不足.
c ++ 11的可变参数模板扩展到救援!
#include <iostream>
struct Window{
void show() {
std::cout << "Window\n";
}
//stuff
}w1, w2, w3;
struct Widget{
void show() {
std::cout << "Widget\n";
}
//stuff
}w4, w5, w6;
struct Toolbar{
void show()
{
std::cout << "Toolbar\n";
}
//stuff
}t1, t2, t3;
template<class...Objects>
void call_show(Objects&&...objects)
{
using expand = int[];
(void) expand { 0, ((void)objects.show(), 0)... };
}
auto main() -> int
{
call_show(w3, w4, w5, t1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
预期产量:
Window
Widget
Widget
Toolbar
Run Code Online (Sandbox Code Playgroud)
另一种更通用的方式(需要c ++ 14):
// note that i have avoided a function names that look like
// one in the standard library.
template<class Functor, class...Objects>
void for_all(Functor&& f, Objects&&... objects)
{
using expand = int[];
(void) expand { 0, (f(std::forward<Objects>(objects)), 0)... };
}
Run Code Online (Sandbox Code Playgroud)
如此称呼:
for_all([](auto& thing) { thing.show(); }, w3, w4, w5, t1);
Run Code Online (Sandbox Code Playgroud)
Max*_*kin 21
另一种选择是使用boost::tupleor std::tuple和boost::fusion::for_each算法:
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/adapted/boost_tuple.hpp>
boost::fusion::for_each(
boost::tie(w1, w2, w3, w4, w5, w6, t1, t2, t3), // by reference, not a copy
[](auto&& t) { t.show(); }
);
Run Code Online (Sandbox Code Playgroud)
出于好奇,将Richard Hodges的方法生成的装配输出与上述方法进行了比较.与gcc-4.9.2 -Wall -Wextra -std=gnu++14 -O3 -march=native生产的汇编代码相同.
nwp*_*nwp 15
基于/sf/answers/482610551/,这可以在不创建额外功能,增强或继承的情况下工作.
标题:
#include <tuple>
#include <utility>
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(const std::tuple<Tp...> &, FuncT) // Unused arguments are given no names.
{ }
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
for_each(const std::tuple<Tp...>& t, FuncT f)
{
f(std::get<I>(t));
for_each<I + 1, FuncT, Tp...>(t, f);
}
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(std::tuple<Tp...> &&, FuncT) // Unused arguments are given no names.
{ }
template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
for_each(std::tuple<Tp...>&& t, FuncT f)
{
f(std::get<I>(t));
for_each<I + 1, FuncT, Tp...>(std::move(t), f);
}
Run Code Online (Sandbox Code Playgroud)
的.cpp:
struct Window{
void show(){}
//stuff
}w1, w2, w3;
struct Widget{
void show(){}
//stuff
}w4, w5, w6;
struct Toolbar{
void show(){}
//stuff
}t1, t2, t3;
int main() {
for_each(std::tie(w3, w4, w5, t1), [](auto &obj){
obj.show();
});
}
Run Code Online (Sandbox Code Playgroud)
Gin*_*lus 11
Window,Widget并Toolbar共享通用接口,因此您可以创建抽象类并使其他类继承它:
struct Showable {
virtual void show() = 0; // abstract method
};
struct Window: Showable{
void show();
//stuff
}w1, w2, w3;
struct Widget: Showable{
void show();
//stuff
}w4, w5, w6;
struct Toolbar: Showable{
void show();
//stuff
}t1, t2, t3;
Run Code Online (Sandbox Code Playgroud)
然后,您可以创建指针数组Showable并迭代它:
int main() {
Showable *items[] = {&w3, &w4, &w5, &t1};
for (auto &obj : items)
obj->show();
}
Run Code Online (Sandbox Code Playgroud)
我推荐Boost.Hana,其中恕我直言是最好,最灵活的模板元编程库.
#include <boost/hana/ext/std/tuple.hpp>
#include <boost/hana.hpp>
namespace hana = boost::hana;
hana::for_each(std::tie(w3, w4, w5, t1), [](auto& obj) { obj.show(); });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5886 次 |
| 最近记录: |