目录一、问题二、解决方案1.定义类型2.定义属性集3. 获取类型索引4. 编译期循环总结一、问题 假设现在有一些属性以及这些属性对应的数值类型,比如: "gender" -->
假设现在有一些属性以及这些属性对应的数值类型,比如:
"gender" --> char
"age" --> int
"height" --> float
"IQ" ---> int
"name" --> std::string
"weight" --> double
在c++中,如何在编译期依次循环获取这些属性的数值类型,并根据对应的数值类型做出相应的处理(属性可能会增加)
首先把所有可能的类型用std::tuple列出:
using Types = std::tuple<float, int, double, std::string, char>;
template<std::size_t N>
using AttributeType = typename std::tuple_element<N, Types>::type;
这里,通过AttributeType<0>就可以得到float 类型
将所有的属性和其类型的对应关系列出,由于需要是编译期获得,必须类似加入constexpr 关键字:
constexpr const char* FLOAT_TYPE = "float";
constexpr const char* INT_TYPE = "int";
constexpr const char* DOUBLE_TYPE = "double";
constexpr const char* STRING_TYPE = "std::string";
constexpr const char* CHAR_TYPE = "float";
constexpr std::array<std::pair<const char*, const char*>, 6> attribute2type = {{
{"gender", CHAR_TYPE},
{"age", INT_TYPE},
{"height", FLOAT_TYPE},
{"IQ", INT_TYPE},
{"name", STRING_TYPE},
{"weight", DOUBLE_TYPE},
}};
根据2中定义的类型字符串,获取1中需要的类型索引N:
constexpr std::size_t getTypeIndex(const char* name)
{
return strings_equal(name, "float") ? 0:
strings_equal(name, "int") ? 1:
strings_equal(name, "double") ? 2:
strings_equal(name, "std::string") ? 3:
strings_equal(name, "char") ? 4:
5; // compilation error
}
这里,需要一个编译期进行字符串比较的函数:
constexpr bool strings_equal(const char* a, const char* b) {
return *a == *b && (*a == '\0' || strings_equal(a + 1, b + 1));
}
如何实现编译期的类似for循环呢,显然不能直接用for,模板的特性决定了可以使用编译期递归来进行替代for循环:
template <typename T>
void print(const char* attribute) {
std::cout << "attribute = " << attribute << ",type=" << typeid(T).name() << std::endl;
}
constexpr size_t LAST_INDEX = attribute2type.size() - 1;
template <size_t T=LAST_INDEX>
struct PrintHelper {
public:
PrintHelper() {
doPrint<T>();
}
private:
template <size_t N>
void doPrint() {
print<AttributeType<getTypeIndex(std::get<N>(attribute2type).second)>>(std::get<N>(attribute2type).first);
doPrint<N-1>();
}
};
template <>
template <>
void PrintHelper<LAST_INDEX>::doPrint<0>() {
print<AttributeType<getTypeIndex(std::get<0>(attribute2type).second)>>(std::get<0>(attribute2type).first);
}
将上面所有的代码放到一块,就得到了一个可以在编译期循环获取变量类型的程序:
#include <string>
#include <iOStream>
#include <typeinfo>
#include <tuple>
#include <array>
using Types = std::tuple<float, int, double, std::string, char>;
template<std::size_t N>
using AttributeType = typename std::tuple_element<N, Types>::type;
constexpr bool strings_equal(const char* a, const char* b) {
return *a == *b && (*a == '\0' || strings_equal(a + 1, b + 1));
}
constexpr std::size_t getTypeIndex(const char* name)
{
return strings_equal(name, "float") ? 0:
strings_equal(name, "int") ? 1:
strings_equal(name, "double") ? 2:
strings_equal(name, "std::string") ? 3:
strings_equal(name, "char") ? 4:
5; // compilation error
}
constexpr const char* FLOAT_TYPE = "float";
constexpr const char* INT_TYPE = "int";
constexpr const char* DOUBLE_TYPE = "double";
constexpr const char* STRING_TYPE = "std::string";
constexpr const char* CHAR_TYPE = "float";
constexpr std::array<std::pair<const char*, const char*>, 6> attribute2type = {{
{"gender", CHAR_TYPE},
{"age", INT_TYPE},
{"height", FLOAT_TYPE},
{"IQ", INT_TYPE},
{"name", STRING_TYPE},
{"weight", DOUBLE_TYPE},
}};
template <typename T>
void print(const char* attribute) {
std::cout << "attribute = " << attribute << ",type=" << typeid(T).name() << std::endl;
}
constexpr size_t LAST_INDEX = attribute2type.size() - 1;
template <size_t T=LAST_INDEX>
struct PrintHelper {
public:
PrintHelper() {
doPrint<T>();
}
private:
template <size_t N>
void doPrint() {
print<AttributeType<getTypeIndex(std::get<N>(attribute2type).second)>>(std::get<N>(attribute2type).first);
doPrint<N-1>();
}
};
template <>
template <>
void PrintHelper<LAST_INDEX>::doPrint<0>() {
print<AttributeType<getTypeIndex(std::get<0>(attribute2type).second)>>(std::get<0>(attribute2type).first);
}
int main() {
PrintHelper<LAST_INDEX>();
return 0;
}
上面程序输出:
$ ./attributeWithType
attribute = weight,type=d
attribute = name,type=NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
attribute = IQ,type=i
attribute = height,type=f
attribute = age,type=i
attribute = gender,type=f
本文通过下面几个技术点实现了编译期循环获取变量类型:
到此这篇关于C++编译期循环获取变量类型详情的文章就介绍到这了,更多相关C++循环获取变量类型内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: C++编译期循环获取变量类型详情
本文链接: https://lsjlt.com/news/167221.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0