像这样的类模板
template <typename... T>
class Action {
private:
std::tuple<T...> m_args;
public:
Action(T... args) : m_args(args...) {}
}
到具有模板成员的类。这样做的原因是只想制作一种类,因此具有不同args的对象仍然属于同一个类,以便于操作。
class Action {
private:
// this does not work, how to declare the tuple type so that It can hold any arguments list.
template <typename... T>
std::tuple<T...> m_args;
public:
template <typename... T>
Action(T... args) : m_args(args...) {}
}
答案 0 :(得分:0)
将您的想法放在编译器的角度。我们可信赖的朋友如何知道Action
需要多少存储空间,如果该大小取决于解析的构造函数?这是不可能的。
template<typename... T>
Action(T... args) : m_args(args...) {}
// wait what???
Action(int someArg) : m_args(someArg) {}
假设第二个构造函数是有效的,或者我们有两个Action
个对象,其中不同的参数传递给构造函数 - 应该是sizeof(Action)
?
如果你遇到这样的问题,可以考虑编译器:可能有些人必须给出足够好的理由,说明为什么不应该支持它,只是因为它只会使实现变得复杂并且还具有性能影响。
由于您提到使用指针而不是聚合对象,我想我会告诉您如何完成此操作。请注意,这会影响性能,因为您现在正在堆上为m_args
分配内存,而不是堆栈。
class Action
{
public:
template<typename... T>
using TArgs = std::tuple<T...>;
std::shared_ptr<void> m_args;
template<typename... T>
Action(T... args)
: m_args(std::make_shared<TArgs<T...>>(args...)) {}
};
Action myAction(1, 2.0, 3.5f);
auto *myActionArgs =
static_cast<Action::TArgs<int, double, float>*>(myAction.m_args.get());
// 2.0
double secondArg = std::get<1>(*myActionArgs);
维护看起来并不好玩。