简体   繁体   English

模板类与模板成员之间的类

[英]template class to class with template member

A class template like this 这样的课程范本

template <typename... T>
class Action {
private:        
    std::tuple<T...> m_args;
public:
    Action(T... args) : m_args(args...) {}
}

to a class with template member. 带有模板成员的类。 The reason why doing this is want to make only one type of class, so that object with different args still belong to the same class for easy manipulation. 之所以这样做,是因为只希望创建一种类型的类,以便具有不同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...) {}
}

Put your mind in the perspective of the compiler. 将您的思维放在编译器的角度。 How would our trusty friend know how much storage is required for Action , if that size would be dependent upon what constructor was resolved? 如果该大小取决于所解析的构造函数,那么我们可信赖的朋友将如何知道Action需要多少存储空间? This is not possible. 这是不可能的。

template<typename... T>
Action(T... args) : m_args(args...) {}

// wait what???
Action(int someArg) : m_args(someArg) {}

Let's say the second constructor was valid, or we had two Action objects with different arguments passed into the constructor -- what should be sizeof(Action) ? 假设第二个构造函数有效,或者我们有两个带有不同参数的Action对象传递给构造函数sizeof(Action)应该是什么?

If you get stuck on an issue like this, think as the compiler: there was probably some person who had to give a good enough reason why it shouldn't be supported, simply because it only complicates the implementation and also has performance implications. 如果您遇到这样的问题,请考虑使用编译器:可能有人必须给出充分的理由说明为什么不应该支持它,这仅仅是因为它只会使实现复杂化并且还影响性能。


Since you mentioned using a pointer instead of an aggregated object, I figured I'd show you how to do this for completeness. 由于您提到使用指针而不是聚合对象,因此我想向您展示如何做到这一点以确保完整性。 Do note that this has performance implications, because you are now allocating the memory for m_args on the heap, rather than the stack. 请注意,这会影响性能,因为您现在在堆而不是堆栈上为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);

This does not look like fun to maintain. 维护起来似乎并不有趣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM