模板类与模板成员的类

问题描述 投票:1回答:1

像这样的类模板

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...) {}
}
c++ templates
1个回答
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);

维护起来看起来并不好玩。

© www.soinside.com 2019 - 2024. All rights reserved.