【发布时间】:2012-02-15 14:41:16
【问题描述】:
保留旧问题。解决方法见下文。 这可能很简单,但仍然如此。我有以下 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 模板化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 的说法,只要参数是引用,编译器就会优化这个前向调用。 现在问题正式结束:)
【问题讨论】:
标签: c++ template-meta-programming