声明模板类型未知的元组
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 允许的接口类型。但这是拥有可以在 运行 时间决定的异构对象集合的标准方法。
我正在编写 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 允许的接口类型。但这是拥有可以在 运行 时间决定的异构对象集合的标准方法。