【问题标题】:C++ use alias template declaration in different classesC++ 在不同的类中使用别名模板声明
【发布时间】:2017-10-12 11:33:15
【问题描述】:

我得到了三个模板类 (Code in C++ Shell) 和一个别名模板 using AType = A<T1,T2>A 中定义。我想在使用 A 对象的文件中使用别名。

所以在B而不是写:

C<A<T1,T2>> c_object;

我希望能够写出类似的东西:

C<typename AType> c_object;

使用A中声明的别名。

// A.h
template<typename T1, typename T2>
class A{
    A();
};
template<typename T1, typename T2>
using AType = A<T1,T2>;

// C.h
template<typename H>
// H = A<T1,T2>
class C{
    C();
};

// B.h
#include "A.h"
template<typename T1, typename T2>
class B{
    B();
    // const C<A<T1,T2>>& GetC() const;
    const C<typename AType>& GetC() const;
private:
    C<typename AType> c_object;
};

注意模板参数的关系。

如果B 只有一个模板参数G 像:

template<typename G>
class B{};

我可以这样做:

C<typename G::AType> c_object;

但由于B 实际上有两个,我无法弄清楚这将如何解决。还是整个问题通常以不同的方式解决?

【问题讨论】:

  • 什么是 G::AType?我很困惑
  • 你的意思是C&lt;AType&lt;T1, T2&gt;&gt;
  • AType 仍然是一个模板,所以无论如何你必须指定模板参数。
  • 什么是 T1 和 T2。你的别名对你没有任何作用。它只是使 AType 等同于 A,因此没有任何改变。你想使用 AType = A
  • @DummySenior:别名模板不会对模板参数进行某种隐式绑定。您要求的内容是不可能的,您必须为A 指定模板参数; T1 和 T2 不会被隐式传递。

标签: c++ c++11 templates using typename


【解决方案1】:

您应该为您的C 类型添加一个usingB

#include "A.h"
template<class T1, class T2>
struct B{
    using C_type =  A<T1, T2>;
    B();
    // const C_type& GetC() const;
    const C_type& GetC() const;
private:
    C_type c_object;
};

或者可以将A 注入B 的模板参数中,这将让调用者有选择地更改它:

#include "A.h"
template<class T1, class T2, template<class, class> class C_T = A<T1, T2>>
struct B{
    B();
    // const C_T& GetC() const;
    const C_T& GetC() const;
private:
    C_T c_object;
}

您误解了模板别名的用途。它们只是使引用其他模板变得更容易;它们不会隐式绑定要传递的模板参数(T1 和 T2 不会在您的 OP 中隐式传递给 A;必须指定 A 的模板参数)。

您可以使用模板别名简化为A 编写模板的C 类型:

template<class T1, class T2>
using C_A = C<A<T1, T2>>;

然后你可以在B 中使用C_A&lt;T1, T2&gt;。如果您需要在多个位置以A 为模板的C,这可能会更加灵活。但是,我上面写的可能更可取;这仅用于演示目的。

【讨论】:

    【解决方案2】:

    问题是AType 不是类型;它是一个模板模板类型。

    如果你写C,你的代码编译如下

    template <template <typename...> class>
    class C 
     { C(); };
    

    并以这种方式传递AType

    template <typename T1, typename T2>
    class B
     {
          B();
          const C<AType>& GetC() const;
       private:
          C<AType> c_object;
     };
    

    但我不明白你想用CAType 做什么

    -- 编辑--

    克劳斯说

    在您发布的代码中,您编写的 C&lt;AType&gt; c_objectwhich 是无效的,因为使用 AType = A;`。我看不到您将任何类型放入别名模板 AType 的位置。因此,您发布的代码没有意义,因为 T1 和 T2 未使用。

    我的回答:我认为我发布的代码“没有意义,因为 T1 和 T2 未被使用”,因为我不理解原始代码的含义。

    但你说我的代码“无效”。

    以下是我使用C&lt;AType&gt; c_objectwhichusing AType = A&lt;T1,T2&gt;; 的代码。请告诉我哪里是无效的以及你在编译时遇到了什么错误。

    template <typename, typename>
    class A { A(); };
    
    template <typename T1, typename T2>
    using AType = A<T1,T2>;
    
    template <template <typename...> class>
    class C { C (); };
    
    template <typename, typename>
    class B
     {
          B();
    
          const C<AType> & GetC () const;
       private:
    
          C<AType> c_object;
     };
    
    int main()
     { }
    
    
    template <typename, typename>
    class A { A(); };
    
    template <typename T1, typename T2>
    using AType = A<T1,T2>;
    
    template <template <typename...> class>
    class C { C (); };
    
    template <typename, typename>
    class B
     {
          B();
    
          const C<AType> & GetC () const;
       private:
    
          C<AType> c_object;
     };
    
    int main()
     { }
    

    【讨论】:

    • B 类在哪里使用 T1 和 T2?它不是隐式地将 T1 和 T2 传递给 AType ...因此,B 被定义为模板,但未使用参数。那有什么好处呢?
    • @Klaus - 不;如果您将 AType 定义为 template&lt;typename T1, typename T2&gt; using AType = A&lt;T1,T2&gt;; 您是说 AType 需要两个模板类型才能成为一个类型;你必须使用(例如)AType&lt;int, long&gt;;你可以写C&lt;AType&lt;T1, T2&gt;&gt; c_object;(如果C必须接收一个类型, but AType`(没有模板参数)不是一个类型
    • 在您发布的代码中,您编写`C c_objectwhich is invalid as using AType = A;`。我看不到您将任何类型放入别名模板 AType 的位置。因此,您发布的代码没有意义,因为 T1 和 T2 未使用。
    • @Klaus - 我在我的回答中转录了完整的编译代码;请解释一下“您发布的代码 [...] 无效”是什么意思。
    • 没用,因为你的 B 类不需要任何模板参数。 AType 被传递给 C,但在那里没有使用。所以我看不到 AType 将被实例化的地方。而作为 AType 别名 A 它也是无用的,因为它什么也没改变。 A 与 AType 相同。那么所有的东西有什么用呢?您之前的代码包含 T1 和 T2 作为 B 的模板参数,因为现在 B 需要 2 个未使用的模板参数。那有什么好处?在您发布更改之前更正了“无效代码”注释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多