C++ 在一个容器中存储不同的模板类,而不会丢失有关它的信息';s型
我目前正在从事一个项目,其中我的应用程序的客户端部分必须能够在服务器上创建自定义模板类。服务器部件必须跟踪这些创建的类,并且必须记住实例化类时使用的类型。问题是,在我的应用程序中大约有36种不同的类模板组合是有效的。我目前正在努力跟踪集合中的这些不同类型,同时又不丢失有关实例的信息 我目前使用的是这样的东西:C++ 在一个容器中存储不同的模板类,而不会丢失有关它的信息';s型,c++,templates,c++14,C++,Templates,C++14,我目前正在从事一个项目,其中我的应用程序的客户端部分必须能够在服务器上创建自定义模板类。服务器部件必须跟踪这些创建的类,并且必须记住实例化类时使用的类型。问题是,在我的应用程序中大约有36种不同的类模板组合是有效的。我目前正在努力跟踪集合中的这些不同类型,同时又不丢失有关实例的信息 我目前使用的是这样的东西: #include <memory> #include <type_traits> #include <vector> enum class data_
#include <memory>
#include <type_traits>
#include <vector>
enum class data_type : std::uint8_t {
type_int = 1,
type_float,
type_double
};
enum class class_type : std:: uint8_t {
type_A = 1,
type_B
};
struct X {
virtual data_type get_data_type() = 0;
virtual class_type get_class_type() = 0;
};
template <typename T>
struct A : X {
data_type get_data_type() override
{
if (std::is_same<T, int>::value) {
return data_type::type_int;
} else if (std::is_same<T, float>::value) {
return data_type::type_float;
} else if (std::is_same<T, double>::value) {
return data_type::type_double;
} else {
/* ... */
}
}
class_type get_class_type() override
{
return class_type::type_A;
}
};
template <typename T>
struct B : X {
data_type get_data_type() override
{
if (std::is_same<T, int>::value) {
return data_type::type_int;
} else if (std::is_same<T, float>::value) {
return data_type::type_float;
} else if (std::is_same<T, double>::value) {
return data_type::type_double;
} else {
/* ... */
}
}
class_type get_class_type() override
{
return class_type::type_B;
}
};
struct Storage {
template <typename T, template <typename> class Class>
void create() {
Class<T>* t = new Class<T>();
_classes.push_back(std::unique_ptr<X>(t));
}
std::vector<std::unique_ptr<X>> _classes;
};
提前感谢。
可以考虑使用<代码> STD::变型< /C> >代码> STD::访问< /COD>模式
auto var = std::variant<int, float, double>{};
// assign var to value
std::visit([](auto& value) {
using Type = std::decay_t<decltype(value)>;
if constexpr (std::is_same<Type, int>{}) {
// is an int
} else if (std::is_same<Type, float>{}) {
// is float
} else if (std::is_same<Type, double>{}) {
// is double
}
}, var);
可以考虑使用<代码> STD::变体< />代码> <代码> STD::访问< /COD>模式
auto var = std::variant<int, float, double>{};
// assign var to value
std::visit([](auto& value) {
using Type = std::decay_t<decltype(value)>;
if constexpr (std::is_same<Type, int>{}) {
// is an int
} else if (std::is_same<Type, float>{}) {
// is float
} else if (std::is_same<Type, double>{}) {
// is double
}
}, var);
正如对问题的评论所述,这是一种可行的方法,有助于:
#include<vector>
#include<memory>
struct Counter {
static int next() {
static int v = 0;
return v++;
}
};
template<typename>
struct Type: Counter {
static int value() {
static const int v = Counter::next();
return v;
}
};
struct X {
virtual int get_data_type() = 0;
virtual int get_class_type() = 0;
};
template <typename T>
struct A : X {
int get_data_type() override {
return Type<T>::value();
}
int get_class_type() override {
return Type<A<T>>::value();
}
};
template <typename T>
struct B : X {
int get_data_type() override {
return Type<T>::value();
}
int get_class_type() override {
return Type<B<T>>::value();
}
};
struct Storage {
template <typename T, template <typename> class Class>
void create() {
Class<T>* t = new Class<T>();
_classes.push_back(std::unique_ptr<X>(t));
}
std::vector<std::unique_ptr<X>> _classes;
};
int main() {
Storage s;
s.create<int, A>();
if(Type<int>::value() == s._classes.front()->get_class_type()) {
//...
};
}
#包括
#包括
结构计数器{
静态int next(){
静态int v=0;
返回v++;
}
};
模板
结构类型:计数器{
静态int值(){
静态常量int v=Counter::next();
返回v;
}
};
结构X{
虚拟int get_data_type()=0;
虚拟int get_class_type()=0;
};
模板
结构A:X{
int get_data_type()覆盖{
返回类型::value();
}
int get_class_type()重写{
返回类型。如问题注释中所述,这是一种可行的方法,可以帮助:
#include<vector>
#include<memory>
struct Counter {
static int next() {
static int v = 0;
return v++;
}
};
template<typename>
struct Type: Counter {
static int value() {
static const int v = Counter::next();
return v;
}
};
struct X {
virtual int get_data_type() = 0;
virtual int get_class_type() = 0;
};
template <typename T>
struct A : X {
int get_data_type() override {
return Type<T>::value();
}
int get_class_type() override {
return Type<A<T>>::value();
}
};
template <typename T>
struct B : X {
int get_data_type() override {
return Type<T>::value();
}
int get_class_type() override {
return Type<B<T>>::value();
}
};
struct Storage {
template <typename T, template <typename> class Class>
void create() {
Class<T>* t = new Class<T>();
_classes.push_back(std::unique_ptr<X>(t));
}
std::vector<std::unique_ptr<X>> _classes;
};
int main() {
Storage s;
s.create<int, A>();
if(Type<int>::value() == s._classes.front()->get_class_type()) {
//...
};
}
#包括
#包括
结构计数器{
静态int next(){
静态int v=0;
返回v++;
}
};
模板
结构类型:计数器{
静态int值(){
静态常量int v=Counter::next();
返回v;
}
};
结构X{
虚拟int get_data_type()=0;
虚拟int get_class_type()=0;
};
模板
结构A:X{
int get_data_type()覆盖{
返回类型::value();
}
int get_class_type()重写{
返回类型。std::variant
?对您有用吗?非常有用。感谢您的输入@skypjack我会将此与@好奇号的设计相结合;您的设计@skypjack确实会使解析A
或B
@reedts添加它作为未来读者的答案。std::variant
?对你有用吗?真的很有帮助。谢谢你的输入@skypjack我会将此与@好奇的设计结合起来;你的设计@skypjack确实会使解析A
或B
@reedts添加它作为未来读者的答案。我想我明白你的想法,但我不确定它是否适用如果我有两个等级的“模板”,那么,在我的例子中,我会有这样的(?):std::vector@reedts如果你用int
,double
和float
实例化了A
,A
和A
进行比较,你只需将替换为相同的,A
,而不是A
谢谢,这真的很有帮助!我正在考虑将这个设计与提供的设计结合起来被@skypjack@Curious每个constexpr if
都将计算为false
,因为decltype(value)
是一个参考。我想我明白你的想法,但我不确定如果我有两个级别的“模板”,它是否适用。因此,在我的情况下,我会有类似(?):std::vector@reedts如果你用int
,double
和float
实例化了A
,A
和A
进行比较,你只需将替换为相同的,A
,而不是A
谢谢,这真的很有帮助!我正在考虑将这个设计与提供的设计结合起来被@skypjack@Curious每个constepr if
都将计算为false
,因为decltype(value)
是一个引用。