[英]C++11 variadic template template parameters
保持旧问题。 请参阅下面的解决方案 它可能很简单,但仍然是。 我有以下C ++ 11代码片段:
#include <vector>
template <typename... Ts>
struct typelist
{
};
template <typename T>
struct EventContainer
{
typedef T Type;
/// TODO. Ring buffer
std::vector<T> container;
void push(const T& t)
{
EventContainer<T>::container.push_back(t);
}
virtual ~EventContainer()
{
}
};
template <template <typename...> class TL>
class EventStorage:
public EventContainer<Ts>...
{
};
class Event1
{
};
class Event2
{
};
typedef typelist<Event1,Event2> Events12;
int main()
{
EventStorage<Events12> ev;
return 0;
}
我怎样才能让EventStorage
继承EventContainer
每个在该类型的templeted typelist
。 我可以用Loki :: library做到这一点,但我想使用带有可变参数模板的C ++ 11。 谢谢。
解决方案1:修复EventStorage
模板模板问题。 这将使EventStorage
,多个继承所有EventContainer
模板化每种类型的Ts
。
template <typename...>
class EventStorage
{
};
template <typename... Ts>
class EventStorage < typelist<Ts...> >:
public EventContainer<Ts>...
{
};
现在我有以下main()
编译时错误:
int main()
{
EventStorage<Events12> ev;
Event1 ev1;
ev.push(ev1);
return 0;
}
In function ‘int main()’:
error: request for member ‘push’ is ambiguous
error: candidates are: void EventContainer<T>::push(const T&) [with T = Event2]
error: void EventContainer<T>::push(const T&) [with T = Event1]
为什么编译器会混淆? 毕竟我推特定类型。 GCC 4.6.1在这里。
分辨率2:由于@Matthieu M.建议我可以提出一个转发方法INT EventStorage
,但在一个额外的载体作用通话的费用:
template <typename T>
void push(const T& t)
{
EventContainer<T>::push(t);
}
根据Alexandrescu的说法,只要参数是引用,编译器就会优化此前向调用。 现在问题正式关闭:)
是否有理由首先介绍typelist
?
template <typename T> struct Template { void push(T) {} };
template <typename... Args>
class Storage: public Template<Args>...
{
public:
// forwarding...
template <typename T>
void push(T t) {
Template<T>& me = *this;
me.push(t);
}
};
int main() {
Storage< int, char > storage;
}
这个工作 ,你可以typedef
整个Storage<...>
位。
编辑 :关于“组合”类型的可能性的评论。
有两种解决方案:
template <typename...> struct CombineStorage;
template <typename... A, typename... B>
struct CombineStorage<Storage<A...>, Storage<B...>> {
typedef Storage<A..., B...> type;
};
或者只是提供一个类型列表适配器:
template <typename... Args>
class Storage<typelist<Args...>>: public Storage<Args...> {};
目前,您甚至从未将类型列表实例化传递给EventStorage,只是类型列表模板 。 所以目前, 没有任何类型的包扩展。
但是,您应该能够使用专业化解压缩类型列表并使用类型包,否则:
template <typename...> class EventStorage;
template <typename Head, typename... Tail> class EventStorage<Head, Tail...>
: public EventContainer<Head>, EventStorage<Tail...>
{
using EventContainer<Head>::push;
using EventStorage<Tail...>::push;
};
// allows you to pass typelists for convenience
template <typename... TL> class EventStorage<typelist<TL...>>
: public EventStorage<TL...>
{
using EventStorage<TL...>::push;
};
using
声明只是将所有push
方法拉入相同的重载集,这似乎对我有用。
另一种方法是添加一个模板方法(可能只是toplevel typelist specialization),它明确地转发到this->EventContainer<T>::push
,但它需要一个精确的类型匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.