具有每个参数类型推导的可变参数构造
我有一个类 Processor
,我希望能够使用 C++14 或更低版本(C++17、20 等想法也非常欢迎信息和子孙后代,但问题具体是 C++14):
- 采用一个可变参数列表进行构造,其中每个元素可以是:
- 基本上任何类型的“值”,或者
Handler
:某种具有do_handle
成员函数的多态类型。
- 在内部将该异构类型列表转换为某种仅包含 Handler 的容器,使用“值”的相关“值”构造函数,并仅复制作为 Handler 传入的内容code>s
- 稍后可以使用其他上下文进行迭代(在下面的情况下,它是一个
int
,但可以是任何东西,例如其他Processor
状态)。
// Handler base class
class Handler {
public:
// "handle" something, somehow
virtual int handle_thing(int foo) const = 0;
}
// Imagine there are "some" Handler derived classes of various kinds
// and say we construct by some factories which look something roughly like the following.
// Factories aren't critical, what's important is you can
// dispatch a given type to a suitable `Handler` implementation
// Factory: copy-constructs a copy of the given handler
// (may use a std::enable_if, whatever)
template<typename SomeHandler>
std::unique_ptr<Handler> make_handler(SomeHandler handler) {
return std::make_unique<SomeHandler>(handler);
}
// Factory: create a handler for some other type
template<typename ValueType>
std::unique_ptr<Handler> make_handler(ValueType value) {
retun std::make_unique<ValueHandler<ValueType>>(value);
}
template<typename ...Types>
class Processor {
public:
// Some number of
Processor(Types&&... args) {
// Something like this pseudo-code:
// for (arg in args) {
// // Construct some suitable handler somehow
// m_handlers.push_back(make_handler(arg));
// }
}
// use the handlers somehow (accumulation here is just an example)
int do_process(int foo) {
int acc = 0;
for (const auto& handler: m_handlers) {
acc += handler->handle_thing(foo);
}
return acc;
}
private:
// Some kind of container of per-argument handlers
// Polymorphism probably indicates container-of-unique_ptr
// but not specifically needed to be so
std::vector<std::unique_ptr<Handler>> m_handlers;
}
我的基本问题是,我不知道如何从类型 Types&&...
的异构构造参数转换为 Handler
的逐元素构造code> 基于每个元素的类型。
我尝试构造一个 std::tuple
,但这似乎对我没有多大帮助,因为如何明智地迭代它并获得它并不明显生成的 Handler 容器。
我还考虑过像这样构建 m_handlers
容器:
std::vector<Handler*, sizeof...(params)> list {args...};
但是由于各个处理程序实际上是不同的类型,因此对我来说这并不明显可以完成。
I have a class Processor
that I'd like to be able to, using C++14 or below (C++17, 20, etc ideas very welcome too for information and posterity, but the problem is specifically C++14):
- Take a variadic list for construction, each element of which can be:
- "values" of basically any type, or
Handler
s: some kind of polymorphic type that has ado_handle
member function.
- Internally convert that heterogeneously-typed list into some kind of container of only
Handler
s, using the relevant "value" constructor for "values", and just copying things that come in asHandler
s - Which can later be iterated over with some other context (in the below case it's an
int
, but that could be anything, e.g. otherProcessor
state).
// Handler base class
class Handler {
public:
// "handle" something, somehow
virtual int handle_thing(int foo) const = 0;
}
// Imagine there are "some" Handler derived classes of various kinds
// and say we construct by some factories which look something roughly like the following.
// Factories aren't critical, what's important is you can
// dispatch a given type to a suitable `Handler` implementation
// Factory: copy-constructs a copy of the given handler
// (may use a std::enable_if, whatever)
template<typename SomeHandler>
std::unique_ptr<Handler> make_handler(SomeHandler handler) {
return std::make_unique<SomeHandler>(handler);
}
// Factory: create a handler for some other type
template<typename ValueType>
std::unique_ptr<Handler> make_handler(ValueType value) {
retun std::make_unique<ValueHandler<ValueType>>(value);
}
template<typename ...Types>
class Processor {
public:
// Some number of
Processor(Types&&... args) {
// Something like this pseudo-code:
// for (arg in args) {
// // Construct some suitable handler somehow
// m_handlers.push_back(make_handler(arg));
// }
}
// use the handlers somehow (accumulation here is just an example)
int do_process(int foo) {
int acc = 0;
for (const auto& handler: m_handlers) {
acc += handler->handle_thing(foo);
}
return acc;
}
private:
// Some kind of container of per-argument handlers
// Polymorphism probably indicates container-of-unique_ptr
// but not specifically needed to be so
std::vector<std::unique_ptr<Handler>> m_handlers;
}
My basic problem is that I don't know how to go from the heterogenous construction arguments of types Types&&...
to an element-by-element construction of a Handler
based on the type of each element.
I have tried to construct a std::tuple<Types...>
, but that doesn't really seem to help me very much, since it's not obvious how to sensible iterate that and get the resulting Handler
container.
I have also thought about constructing the m_handlers
container like this:
std::vector<Handler*, sizeof...(params)> list {args...};
But since the individual handlers are actually different types, it's not obvious to me that that can be done.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 C++11 和 C++14 中,您可以使用 大括号封闭初始化器 用于扩展和处理可变参数。因此,在您的情况下,您可以执行
自 C++17 起,您还可以使用 折叠表达式< /a> 配合逗号操作符可以达到同样的效果:
In C++11 and C++14 you can use brace-enclosed initializers to expand and handle variadic arguments. So in your case you could do
Since C++17 you can also use a fold expression with the comma operator to achieve the same effect: