我有一个算法(这里没有预设),它以不同的参数(int、float、vectors)作为输入。
我的设计想法是有一个容器来容纳所有这些不同的参数。
为此,我有一个基类Parameter 和一个派生模板类TypeParameter。
这些参数将保存在一个容器中。
设计如下:
#pragma once
#include <utility>
#include <memory>
#include <string>
#include <vector>
namespace parameter
{
/*
Interface for parameter
*/
class Parameter
{
public:
Parameter() {}
Parameter(std::string param_name) : name(param_name) {}
Parameter(const Parameter&& other) noexcept : name(std::move(other.name)) {}
virtual ~Parameter() {}
inline const std::string get_name() { return name; }
private:
std::string name;
};
/*
*/
template<class T>
class TypeParameter
: public Parameter
{
public:
TypeParameter(std::string param_name, T new_value) : Parameter(param_name), value(new_value) {}
TypeParameter(const TypeParameter&& other) noexcept : Parameter(std::move(other)), value(std::move(other.T)) {}
inline const T get_value() { return value; }
private:
T value;
};
/*
Container for parameters
*/
class ParameterSet
{
public:
ParameterSet() {}
void add(std::unique_ptr<Parameter> param) { data.push_back(std::move(param)); }
private:
std::vector <std::unique_ptr<Parameter>> data;
};
} //namespace parameter
主要是:
#include <iostream>
#include <string>
#include "Parameter.h"
using parameter::TypeParameter;
using parameter::Parameter;
using parameter::ParameterSet;
void foo(std::unique_ptr<Parameter> p)
{
std::cout << p->get_value(); // ERROR
}
int main(int argc, char *argv[])
{
TypeParameter<int> *iparam = new TypeParameter<int>("ee", 3);
std::unique_ptr<Parameter> p = std::make_unique <TypeParameter<int>>("foo", 3);
foo(std::move(p));
ParameterSet param_set;
param_set.add(std::unique_ptr<Parameter>(iparam));
param_set.add(std::move(p));
getchar();
}
我的问题是我无法在没有类型转换的情况下获得值(value)。
因此,我的问题是如何将 unique_ptr 从参数类转换为派生的 TypeParameter。 还有另一种设计容器的方法吗?
非常感谢!
最佳答案
您不必重新发明轮子。您可以使用标准库中的几个类:
std::variant
.
正如评论所建议的那样,variant
是一组预定义数据类型的类型安全 union ,您将其放入 variant
的模板参数中.
例如,std::variant<int,float,double>
可以容纳 int
类型的任何值, float
, 或 double
, 但没有别的。
要使用存储值,您可以将访问者模式与 std::visit()
一起使用功能。其他函数允许您知道哪些预设类型存储在变量 ( index()
) 中并从中提取值(使用 get()
)。如果您尝试提取错误类型的值,get()
函数抛出异常
std::any
是另一个可以保存不同数据类型的实用程序。相对于 variant
,您不必在编译时知道类型。基本上,它存储一个 void*
使用 typeinfo
的数据记住它的原始类型。然后您可以使用 any_cast
将变量转换回其原始类型。就像variant
,当尝试转换为错误的类型时会抛出异常。
这两个类在 C++ 17 中可用。如果您无法使用这些功能,它们也包含在 boost 中(分别为 boost:variant
和 boost:any
)
您可以将一组值存储在标准库容器中,例如在std::vector<std::variant<int,float,double>>
或 std::vector<std::any>>
.
关于c++ - 模板类的唯一容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52185857/