如何访问模板包参数的模板参数
How do I get access to template parameters of a template pack parameter
我正在尝试创建一个模板类,该类将使比较函数能够返回一个整数[0-equal,>0 a应该先到,<0 b应该先到]。
我正在使用排序结构模板参数来跟踪应该使用的类型、字符串中字段的偏移量以及该字段应该保留的顺序。。。所以比较可以根据返回正确的值。
现在假设std::string
用于表示序列化的值。
我在从模板中提取信息时遇到问题。我保留了sort
作为一个pack参数,它的类型是Sort
。如何访问代码中的这些参数?如果有更好的方法来重构它。我研究了一些与模板相关的其他问题,但没有发现任何能解决这个问题的问题。我使用的是gcc8.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
的特定实例化,但实际上您接受了类模板。。。如CCD_ 5。这大概没有什么意义。
但当我们这样做的时候,我们不仅只接受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)
等等。
我将从另一个方面来解决这个问题:如果T
有模板参数,如何提取模板参数?这里有一个例子:
template<typename T>
void foo(T v) {
// T is std::vector<int>, how to extract `int`?
}
int main() {
foo(std::vector{1, 2, 3, 4});
}
对此有很多答案:使用部分专业化提取、键入别名等。
以下是如何为std::vector
:执行此操作
template<typename>
struct extract_value_type_t {};
template<typename T>
struct extract_value_type_t<std::vector<T>> {
using type = T;
};
template<typename T>
using extract_value_type_t = typename extract_value_type<T>::type;
template<typename T>
void foo(T v) {
// with template specialization
using value_type = extract_value_type_t<T>;
// with the member alias std::vector exposes
// needs much less boilerplate!
using value_type = typename T::value_type;
}
当T
是一个向量时,它给我们带来了什么?好吧,如果你可以用一个简单的类型T
做一些事情,你甚至不需要模板模板参数,这会使你的界面更加灵活:
template<typename>
struct sort_traits {};
template<typename T, uint32_t offset_, char order_>
struct sort_traits<Sort<T, offset_, order_>> {
using type = T
static constexpr auto offset = offset_;
static constexpr auto order = order_;
};
然后在你的Comparator
类中,简单地做一些类似的事情:
template<uint32_t keyLength, typename... sorts>
struct Comparator {
int compare(std::string const& a, std::string const& b) {
return (internal_compare<sorts>(a.data(), b.data()) && ...);
}
private:
template<typename sort>
int internal_compare(char const* a, char const* b) {
using traits = sort_traits<sort>;
using type = typename traits::type;
constexpr auto offset = traits::offset;
constexpr auto order = traits::order;
// do stuff
}
};
这也增加了有一天添加另一种排序的可能性,这种排序将具有不同的模板参数或不同的内容。
相关文章:
- 使用不带参数的函数访问结构元素
- 从C++dll访问C#中的一行主要参数
- 函数是否可以访问传递给main()的参数
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 如何从其他功能C++访问参数?
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 如何访问模板参数自己的模板参数?
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 如何访问QT中传递给程序的参数
- 从模板参数包实例化的访问类实现
- 限制多模板参数朋友函数可访问的类实例的范围
- 在将向量作为参数传递给函数后,我无法访问函数中向量的元素
- 使用指针访问参数接收的结构中的元素时内存泄漏
- 从析构函数访问模板类构造函数的参数,可以吗?
- 仅当构造函数具有参数时,C++ 公共成员才能访问
- C/C++ 包含点的宏参数(成员访问运算符)
- 如何使用 int 参数循环访问模板函数
- 模板参数包访问第 N 个类型和第 N 个元素
- "return-by-reference"或"pass-by-reference"参数何时与constexpr兼容?
- 在模板类中使用结构体作为参数并访问它们的元素