首页 > 解决方案 > 如何访问模板包参数的模板参数

问题描述

我正在尝试创建一个模板类,它将使比较函数能够返回一个整数 [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)));
         }
      }
};

有两件事我没能完成。

链接到编译器资源管理器上的代码

标签: c++templatesc++17

解决方案


如果不使用这种形式,这将变得更加容易:

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)

等等。


推荐阅读