代码之家  ›  专栏  ›  技术社区  ›  francesco

包装任意类型/非类型模板类的模板类

  •  5
  • francesco  · 技术社区  · 7 年前

    假设我有一个模板类 base 和一个班 wrapper 其中包含的实例化成员 基础 .我想定义班级 包装 这样它就依赖于模板参数包,而模板参数包只是简单地“传递”给 基础 .

    例如,考虑下面的代码,它工作得很好。

    #include <iostream>
    
    template <int i, int j>
    struct base {
      base()
      {
        std::cout << "i is " << i;
        std::cout << " j is " << j << std::endl;
      }
    };
    
    template <int... T>
    struct wrapper {
      base<T...> a;
    };
    
    int main()
    {
      wrapper<2, 3> x;
      return 0;
    }
    

    预先知道所有模板参数 基础 int ,我用 template <int...T> 在声明中 包装 .这允许有限的灵活性,例如,我可以为模板参数定义一些默认值 基础 ,不修改 包装 .

    但是,如果 基础 根据类型和非类型模板参数的仲裁列表,我如何传递 包装 基础 是吗?

    例如,如果我知道 基础 可以隐式转换为int(不丢失!),我可以定义 包装 如下程序所示

    #include <iostream>
    
    template <int i, bool j>
    struct base {
      base()
      {
        std::cout << "i is " << i;
        std::cout << " j is " << (j ? "true" : "false") << std::endl;
      }
    };
    
    template <int... T>
    struct wrapper {
      base<T...> a;
    };
    
    int main()
    {
      wrapper<2, true> x;
      return 0;
    }
    

    但是如果 基础 同时取决于类型和非类型模板参数,如以下程序中所示,显然不可能简单地传递 包装 基础 以下内容:

    #include <iostream>
    
    template <class U, int i, int j>
    struct base {
      base()
      {
        std::cout << "i is " << i;
        std::cout << " j is " << j << std::endl;
      }
    };
    
    template <class... T>
    struct wrapper {
      base<T...> a;
    };
    
    int main()
    {
      wrapper<int, 2, 3> x; // Error!
      return 0;
    }
    

    此程序不编译,因为编译器需要 包装 .

    有写班级的方法吗 包装 将其模板参数“传递”到类型的成员 基础 ,请 不管是什么 是吗?

    我们的想法是为 包装 如果模板签名 基础 变化。

    1 回复  |  直到 7 年前
        1
  •  1
  •   bartop    7 年前

    你的问题有解决办法。它不是很优雅,需要特定的方法,但在您需要的情况下工作:

    template <class U, class i, class j>
    struct base {
      base()
      {
        std::cout << "i is " << i::value;
        std::cout << " j is " << j::value << std::endl;
      }
    };
    
    template <class ...T>
    struct wrapper {
      base<T...> a;
    };
    
    int main()
    {
      wrapper<int, std::integral_constant<int, 2>, std::integral_constant<int, 3>> x; //no error now!
      return 0;
    }
    

    用C++ 17可以减少冗长:

    template<auto val>
    using value_wrapper = std::integral_constant<decltype(val), val>;
    
    int main()
    {
      wrapper<int, value_wrapper<2>, value_wrapper<3>> x; //no error now!
      return 0;
    }