Dra*_*nov 6 c++ template-meta-programming
保持旧问题.请参阅下面的解决方案 它可能很简单,但仍然是.我有以下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;
}
Run Code Online (Sandbox Code Playgroud)
如何使EventStorage继承EventContainer与每种类型的模板typelist.我可以用Loki :: library做到这一点,但我想使用带有可变参数模板的C++ 11.谢谢.
解决方案1:修复EventStorage模板模板问题.这将使EventStorage多个继承所有EventContainer模板化的每种类型Ts.
template <typename...>
class EventStorage
{
};
template <typename... Ts>
class EventStorage < typelist<Ts...> >:
public EventContainer<Ts>...
{
};
Run Code Online (Sandbox Code Playgroud)
现在我有编译时错误,如下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]
Run Code Online (Sandbox Code Playgroud)
为什么编译器会混淆?毕竟我推特定类型.GCC 4.6.1在这里.
解决方案2:正如@Matthieu M.建议我可以提供一个转发方法int EventStorage,但需要花费一个额外的功能调用:
template <typename T>
void push(const T& t)
{
EventContainer<T>::push(t);
}
Run Code Online (Sandbox Code Playgroud)
根据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;
}
Run Code Online (Sandbox Code Playgroud)
这有效,你可以做到typedef这Storage<...>一点.
编辑:关于"组合"类型的可能性的评论.
有两种解决方案:
template <typename...> struct CombineStorage;
template <typename... A, typename... B>
struct CombineStorage<Storage<A...>, Storage<B...>> {
typedef Storage<A..., B...> type;
};
Run Code Online (Sandbox Code Playgroud)
或者只是提供一个类型列表适配器:
template <typename... Args>
class Storage<typelist<Args...>>: public Storage<Args...> {};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3005 次 |
| 最近记录: |