【问题标题】:If template parameter AA is a templatized class A<T> itself, is it possible to get the template parameter (T) of this templatized class?如果模板参数AA本身就是一个模板化的类A<T>,那么是否可以得到这个模板化类的模板参数(T)呢?
【发布时间】:2020-12-15 14:40:07
【问题描述】:

考虑下面的代码:

template <typename T>
class A{
...
}

template <class U>
class B{
...
}

int main {
B<A<int>> a;
...
}

如果 A 是 B 的模板参数,我如何在 B 中获取 A 的模板参数(在本例中为 int)? 我可以将 B 参数化如下,但我觉得我发送了一条不必要的信息。

template <class AA, typename T>
class B { ... }

我不简单地将template &lt;typename T&gt; 用于B 类的原因是我在B 中有一个指向A 类的指针,我想使用模板参数class AA 来查看该指针是否为const,因此B 中的成员指针的类型正确。

【问题讨论】:

  • 您可以像template&lt;typename T&gt; class B&lt;A&lt;T&gt;&gt; { /* whatever */ }; 那样对它进行部分专业化。您自己的解决方案也没有什么坏处。您的问题太模糊,无法给出更具体的答案。
  • @TanveerBadar,感谢您的回答。 B 类应该始终将 A 作为模板参数。真正的参数是 T(以及 A 的常量)。
  • 那么,为什么不使用template &lt;typename T&gt; class B{ A&lt;T&gt; X; ...}; 呢?
  • @Damien,因为我有 'A* X' 或 'const A* X' 取决于 A 是否为 const。假设 A 是一个非常大的类,我想在 B 中有一个指向该类的指针,但同时 A 可能是 const 或不是。我在这里问了另一个问题:stackoverflow.com/q/65286216/10755448
  • 我看不出它有什么变化。你可以有 `template class B{ A *X;常量 A *Y; ...}; ...

标签: c++ templates template-templates non-type-template-parameter


【解决方案1】:

有几种方法,取决于你可能会改变:

  • 快速方法,专业 B

    template <class> class B;
    
    template <class T>
    class B<A<T>>
    {
        // Use directly T
        //...
    };
    
  • 直接在A 中添加信息(就像标准容器对value_type 所做的那样)

    template <typename T>
    struct A
    {
        using my_type = T;
    };
    
    // Then in `B<U>`, use `typename U::my_type`
    
  • 使用外部特征从A(如std::iterator_traits)中提取信息(这也允许处理内置类型):

    template <typename T>
    struct ATrait;
    
    template <typename T>
    struct ATrait<A<T>>
    {
        using my_type = T;
    };
    
    // Possibly a generic one
    template <template <typename> class C, typename T>
    struct ATrait<C<T>>
    {
        using my_type = T;
    };
    
    // Then in `B<U>`, use `typename ATrait<U>::my_type`
    

【讨论】:

    【解决方案2】:

    我认为以下内容可以满足您的要求:

    #include<type_traits>
    template<class>
    class A{};
    
    template<class>
    struct get_inner;
    
    template<template<class> class TT, class T>
    struct get_inner<TT<T>> {
        using outer = TT<T>;
        using inner = T;
    };
    
    template<class TT>
    struct B {
        using A = TT;
        using inner = typename get_inner<std::decay_t<A>>::inner;
    };
    
    
    int main(int argc, char *argv[])
    {
        static_assert(std::is_const_v<typename B<const A<int>>::A>);
            static_assert(!std::is_const_v<typename B<A<int>>::A>);
    }
    

    注意std::decay_t,它不能直接与const 参数一起使用(因此我们不能只以这种方式专门化B)。也许decay_t 有点强,但它有效^^

    【讨论】:

      【解决方案3】:

      试试这个

      template <typename X> class B;
      
      template <template <typename> class XX, typename T>
      class B<XX<T>>
      {
          // your implementation
      };
      
      B<A<int>> a;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-21
        • 2018-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多