[英]How to expand variadic template class
Simplified I'm trying the following:简化我正在尝试以下操作:
template<typename T>
struct SomeObject
{
T value;
};
template<typename... Ts>
struct Container : public SomeObject<Ts>...
{
void init()
{
(initObject<Ts>())...; // not working: how to execute initObject for each type
}
template<typename T>
void initObject()
{
SomeObject<T>::value = new T();
// do some other stuff
}
};
class A {};
class B {};
int main()
{
auto c = new Container<A, B>();
c->init();
}
In my use case I cannot do the initialization in the constructor.在我的用例中,我无法在构造函数中进行初始化。 So how can I get the
init
method to properly expand for all types?那么我怎样才能让
init
方法正确地扩展所有类型呢?
In c++17, you can do it with a fold expression over the comma operator在 c++17 中,您可以在逗号运算符上使用折叠表达式来完成
(initObject<Ts>(), ...);
before c++17 you could do something like在 c++17 之前你可以做类似的事情
std::initializer_list<int>{(initObject<Ts>(), 0)...};
Note the comma experssion in the initializer list.注意初始化列表中的逗号表达式。 It is there because
initObject
returns void
, and you cannot have an initializer_list
of void
s它在那里是因为
initObject
返回void
,并且您不能拥有void
的initializer_list
Here is another more general solution.这是另一个更通用的解决方案。 It is too complex for this case, but may be useful.
对于这种情况,它太复杂了,但可能很有用。
template<typename... Ts>
struct Container : public SomeObject<Ts>...
{
void init()
{
initObjects<Ts...>(); // not working: how to execute initObject for each type
}
template <typename ...Args>
struct object_initializer;
template <typename First, typename ...Rest>
struct object_initializer<First, Rest...> {
void operator ()() {
SomeObject<First> obj{First()};
object_initializer<Rest...>()();
}
};
template <typename First>
struct object_initializer<First> {
void operator ()() {
SomeObject<First> obj{First()};
}
};
template<typename ...Args>
void initObjects() {
object_initializer<Args...>()();
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.