我有一个小的C ++类,它包装一些基本类型的类型信息。简化版本如下:
struct TypeInfo {
TypeInfo(std::size_t elm_size, const std::string& type_name) :
elm_size(elm_size),
type_name(type_name)
{}
std::size_t elm_size;
std::string type_name;
}
TypeInfo double_info(sizeof double, "double");
TypeInfo int_info(sizeof int, "int");
这有效-但我希望能够基于常规C ++模板实例化TypeInfo
对象;即是这样的:
TypeInfo<double> double_info; // <- This does not work
由于此类本身不包含任何T
-它实际上不是模板化的类-而是一种方便的实例化方法。当这包含在真正模板化的函数中时:
void vector_operation(const std::vector<T>& data) {
TypeInfo<T> type_info; // <- This does not work!
}
如果我可以基于模板参数实例化TypeInfo
实例,将对真的有所帮助。由于我只需要介绍少数几个基本类型-float, double, int
和char
,所以我很乐意显式地专门化少数几个类型。
更新:@nathan_oliver建议将整个类作为模板,然后使用sizeof(T)
确定元素的大小。该解决方案的问题(如我所见)-用户仍然需要提供type_name
字符串(以及一些特定于类型的信息)-我想专门说明我需要的几种类型-然后完全指定:
template <typename T>
struct TypeInfo {
TypeInfo();
std::size_t elm_size;
std::string type_name;
}
然后在.cpp文件中:
template<>
TypeInfo::TypeInfo<double>() {
this->elm_size = sizeof(double);
this->type_name = "double";
}
template<>
TypeInfo::TypeInfo<int>() {
this->elm_size = sizeof(int);
this->type_name = "int";
}
但这甚至无法编译:
type_info.cpp:46:5: error:
invalid use of template-name ‘TypeInfo’ without an argument list
TypeInfo::TypeInfo()
答案 0 :(得分:1)
如果您确实只对少数几个基本类型感兴趣,并且可以手动对其进行专门化,那似乎是个不错的选择。
template <typename T>
struct TypeInfo; // default values could go here for un-specified types
template <>
struct TypeInfo<int> {
const std::size_t elm_size = sizeof(T);
const std::string type_name = "int";
}
// more specializations for double, char and float
然后,您只需通过模板参数实例化即可使用它。
如果存在不同的TypeInfo
实例类型不同的事实,则可以使用一个函数,该函数根据传递给该函数的参数返回一个正确的TypeInfo
对象,并为其设置正确的值
template <typename T>
TypeInfo get_type_info() {
return TypeInfo{sizeof(T), "unknown"};
}
template <>
TypeInfo get_type_info<int>() {
return TypeInfo{sizeof(T), "int"};
}
auto type_info = get_type_info<int>();
答案 1 :(得分:0)
由于不能调用构造函数,因此不能将类构造函数用作模板,也不能指定模板类型。
您可以将类设为模板,并使用模板类型获取类型的大小,而不是由用户提供。那会给你
template<typename T>
struct TypeInfo {
TypeInfo(const std::string& type_name) :
type_name(type_name)
{}
std::size_t elm_size = sizeof(T);
std::string type_name;
};
TypeInfo<double> double_info("double");
TypeInfo<int> int_info("int");
答案 2 :(得分:0)
您不能为构造函数指定模板参数。他们只能被推论。您可以将类型标签发送到构造函数:
template<typename> struct tag_t {};
template<typename T> inline constexpr auto tag = tag_t<T>{};
struct TypeInfo {
template<typename T>
TypeInfo(tag_t<T>) :
elm_size{sizeof(T)},
type_name{/* find a way to get name */} {}
std::size_t elm_size;
std::string type_name;
};
TypeInfo double_info{tag<double>};
TypeInfo int_info{tag<int>};
您将必须找到一种从模板参数获取类型名称的方法。为此存在一些库,例如ctti
答案 3 :(得分:0)
另一种解决方案是使用辅助函数。
struct TypeInfo {
TypeInfo(std::size_t elm_size, const std::string& type_name) :
elm_size(elm_size),
type_name(type_name)
{}
std::size_t elm_size;
std::string type_name;
};
template <typename T>
TypeInfo make_TypeInfo(const std::string& type_name)
{
return TypeInfo(sizeof(T), type_name);
}
并使用
TypeInfo double_info = make_TypeInfo<double>("double");
TypeInfo int_info = make_TypeInfo<int>("int");