声明模板类型未知的元组

Declaring a Tuple whose template type is unknown

我正在编写 C++ 代码来管理磁盘上一些变量的写入。我已经编写了整个体系结构,用户剩下的就是填充方法,他在其中指定如何计算每个变量。为此,我创建了一个模板容器,用户可以在其中指定变量名称和计算变量的 std::function:

template <typename T> struct Container {
    Container<T>(std::string _name, std::function<T()> _f): name(_name), f(_f){

    }

    std::string name;
    std::function<T()> f;
    T *var;

    void assign(int i){
        var[i] = f();
    }
}

然后,对于用户需要添加的每个变量,他只需创建一个新容器 object。例如:

std::string returnTime(){
   // Do stuff and returns time;
   return time;
}

Container<std::string>("time",returnTime);

现在我的问题是我需要存储所有类型的容器,所以我考虑使用 std::tuple。我的实际代码如下:

Dst.cpp

Dst::registerVariables(){
            variables = std::make_tuple
            (
             Container<unsigned int>("Run", [this](){return ev ? ev -> Run() : -1;}),
             Container<unsigned int>("Event", [this](){return ev ? ev -> Event() : -1;}),
             Container<unsigned int>("UTime", [this](){return ev ? ev -> UTime() : -1;}),
             Container<double>("ThetaS", [this](){return ev ? ev -> fHeader.ThetaS  : 0;})
            );
}

现在我的实际问题是 header 中元组 object "variables" 的声明,因为声明时不知道类型。

Dst.hpp

class Dst : public DstAmsBinary{
public:
    Dst( std::string _data ) : DstAmsBinary( _data, MAXRAM){
        std::cout << "init with #" << data.size() << std::endl;
    }

protected:
    void registerVariables();
    auto variables;
};

我所能想到的就是尝试 "auto" 关键字,但当然没有用。

所以我的问题归结为: 我如何构建一个 super-container 来存储我的模板 Container objects 的列表,无论它们的模板类型是什么。

也许将列表存储在元组中只是错误的想法。我正在寻找建议(可能与其他模板容器或计算元组类型的预处理器宏...)

如果您已读完此消息,感谢阅读 ;-)

处理这个问题的方法是让您的 Container class 模板继承自作为接口的基础 class:

template <typename T>
class Container : public Base {
  // ....
};

然后每当注册变量时,一切都根据基类型注册:

std::vector<Base> variables;
variables.push_back( Container<unsigned>("Run"  , [this](){return ev ? ev -> Run()   : -1;} ) );
variables.push_back( Container<unsigned>("Event", [this](){return ev ? ev -> Event() : -1;} ) );
// etc.

您可能需要创建指向这些对象的智能指针并将它们推回,具体取决于您的情况(即,如果 Base 是一个抽象接口,希望它会是)。您还需要考虑通过 Base class 允许的接口类型。但这是拥有可以在 运行 时间决定的异构对象集合的标准方法。