【问题标题】:template non-type template parameter模板非类型模板参数
【发布时间】:2021-03-18 21:48:28
【问题描述】:

我正在尝试使用 C++20 功能简洁地编写一个 constexpr 常量。

#include <utility>

template <template <typename T, T ... Ints> std::integer_sequence<T, Ints...> I>
static constexpr long pow10_helper = ((Ints, 10) * ...);

template <std::size_t exp>
static constexpr long pow10 = pow10_helper< std::make_index_sequence<exp> >;

static_assert(pow10<3> == 1000);

但它既不在 GCC 也不在 clang 上编译。

是否可以指定模板非类型模板参数? 或者,可以递归地编写它,但很高兴知道是否可以像上面那样编写它。

请注意,这个问题看起来类似于 Template template non-type parameter 但是非类型模板参数放在嵌套模板参数列表中,而不是放在主参数列表中。

【问题讨论】:

    标签: c++ constexpr c++20 template-templates


    【解决方案1】:

    你可以这样做:

    #include <utility>
    
    template<class T>
    static constexpr long pow10_helper;
    
    template<class T, T... Is>
    static constexpr long pow10_helper<std::integer_sequence<T, Is...>> = ((Is, 10) * ...);
    
    template <std::size_t exp>
    static constexpr long pow10 = pow10_helper<std::make_index_sequence<exp> >;
    
    static_assert(pow10<3> == 1000);
    

    【讨论】:

      【解决方案2】:

      您不能直接将参数引用到模板模板参数。它们不在范围内。但你可以这样做:

      #include <utility>
      
      template <class>
      class pow10_helper {};
      
      template <template <typename T, T ...> class IntSeq, class T, T ... Ints>
      struct pow10_helper<IntSeq<T, Ints...>> {
        static constexpr long value = ((Ints, 10) * ...);
      };
      
      template <size_t pow>
      static constexpr long pow10 = pow10_helper<std::make_index_sequence<pow>>::value;
      
      #include <iostream>
      int main() {
        size_t pow = pow10<3>;
        std::cout << pow << std::endl; // prints 1000
      }
      

      话虽如此,有更简单的方法来实现pow10

      template <size_t pow>
      struct pow10 { static constexpr size_t value = 10 * pow10<pow-1>::value; };
      template <> struct pow10<0> { static constexpr size_t value = 1; };
      
      int main() {
        size_t pow = pow10<3>::value;
        std::cout << pow << std::endl; //prints 1000
      }
      

      【讨论】:

      • 更重要的是,您不能以这种方式声明模板参数(如果确实有效,这实际上需要integer_sequence 类型的object)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-06
      • 2014-10-03
      • 1970-01-01
      相关资源
      最近更新 更多