c++ - 如何访问模板包参数的模板参数
问题描述
我正在尝试创建一个模板类,它将使比较函数能够返回一个整数 [0 - 相等,>0 a 应该首先出现,<0 b 应该首先出现]。
我正在使用 Sort structs 模板参数来跟踪应该使用的类型、字符串中字段的偏移量以及应该保留该字段的顺序......所以比较可以根据返回正确的值。
现在假设 用于std::string
表示序列化值。
我无法从模板中提取信息。我保留sort
了一个包参数,它的类型是Sort
. 如何在代码中访问这些参数?如果有更好的方法来重构它。我查看了与模板相关的其他一些问题,但没有看到任何可以解决此问题的问题。我正在使用 gcc 8.2 和 c++17。
#include <cstdint>
#include <string>
#include <cstring>
#include <cassert>
template<typename T, uint32_t offset, char Order = 'A'>
struct Sort {};
template<uint32_t keyLength, template<typename T,uint32_t offset, char Order> class ... sort>
class Comparator {
public:
int compare(std::string & a, std::string &b) {
assert(a.length()==b.length());
// How would I sum the sizeof each T. i.e. if T is int and another T is short, then sum should be 6+keyLength?
assert(a.length()==(sizeof(T)+keyLength)); // Check that my length is equal to key length + all type lengths put together
auto r = memcmp(a.data(),b.data(),keyLength);
if(r!=0) return r;
// How do I retrieve T,offset,Order of each pack parameter.
return internal_compare<T,offset,Order>(a.data(),b.data())? internal_compare<T,offset,Order>(a.data(),b.data()) : ...;
}
private:
template<typename IT,uint32_t iOffset, char iOrder>
int internal_compare(char * a,char *b) {
if constexpr (iOrder=='A'||iOrder=='a') {
return (*(static_cast<IT *>(a+iOffset)))-(*(static_cast<IT *>(b+iOffset)));
} else {
return (*(static_cast<IT *>(b+iOffset)))-(*(static_cast<IT *>(a+iOffset)));
}
}
};
有两件事我没能完成。
- 一个是从排序中获取 sizeof(T) 的总和。
- 在每个排序上调用内部比较运算符。
解决方案
如果不使用这种形式,这将变得更加容易:
template<typename T, uint32_t offset, char Order = 'A'>
struct Sort {};
template<uint32_t keyLength, template<typename T,uint32_t offset, char Order> class ... sort>
class Comparator;
你用这个:
template <uint32_t keyLength, class...>
class Comparator;
template <uint32_t keyLength, typename... T, uint32_t... offset, char... Order>
class Comparator<keyLength, Sort<T, offset, Order>...> {
// ...
};
首先,原版并没有做你想做的事。您想要特定的实例化,Sort
但实际上您正在接受类模板......比如Comparator<32, Sort, Sort, Sort>
. 这大概没有意义。
但是当我们这样做时,我们不仅接受实例化,Sort
而且我们拥有最有用形式的参数。所以是这样的:
// How would I sum the sizeof each T. i.e. if T is int and another T is short,
// then sum should be 6+keyLength?
是一个折叠表达式:
(sizeof(T) + ... + keyLength)
等等。
推荐阅读
- rust - 在 Diesel 中关联三个表(多对多关系)的标准模式是什么?
- java - 如何将双精度类型值添加到 JTable 行?
- java - change type of object into type I created in java
- android - 获取系统属性的有效替代反射
- angular - 角垫选择下拉返回一个未定义的值
- javascript - 我正在尝试实施 VeeValidate 以检查是否至少选中了一个复选框
- reactjs - Get specific enum member from int in Typescript
- javascript - 在 JavaScript 中检查数组的数据类型和空值
- sql - 导入 CSV 时 SQL Server 字符串转换为 int 错误
- php - 我们可以通过使用 php 中的 mailto 函数来隐藏按钮并检查邮件是否已发送来获得回电吗?