解耦嵌套类:"冲突的模板声明"使用模板别名时出错

时间:2017-08-30 23:45:32

标签: c++ nested

根据this question的建议,我使用了后期模板实例化来解耦两个类testTemplateBuilderA,它们互相引用:

B

以上编译没有错误。

但是,如果我尝试在别处实现#include <iostream> #include <memory> template <typename T> class Bbase { }; template <typename T> class BImpl; template <typename T> class AImpl { public: typedef boost::shared_ptr<AImpl> Ptr; typename BImpl<T>::Ptr foo(); }; template <typename T> class BImpl { public: typedef boost::shared_ptr<BImpl> Ptr; typename AImpl<T>::Ptr bar(); }; typedef AImpl<void> A; typedef BImpl<void> B; int main () { A a; B b; return 0; } 并定义别名类,我会收到以下编译错误:

B

编译器:

#include <iostream>
#include <memory>

template <typename U>
class Bbase {
public:
    typedef std::shared_ptr<Bbase> Ptr;
    typename U::Ptr bar();
};      

template <typename T> class BImpl;

template <typename T>
class AImpl
{
public:
    typedef std::shared_ptr<AImpl> Ptr;
    typename BImpl<T>::Ptr foo();
};

template <typename T>
using BImpl = Bbase< AImpl<T> >;

typedef AImpl<void> A;
typedef BImpl<void> B;

int main () {
        A a;
        B b;
        return 0;
}

我理解编译器错误,我正在尝试重新定义模板,但我不理解:

  • 为什么第一个代码段有效?是第一种情况下的实施和后者的(重新)定义吗?
  • 我可以将$ g++ foo.cpp --std=c++14 foo.cpp:22:32: error: conflicting declaration of template ‘template<class T> using BImpl = Bbase<AImpl<T> >’ using BImpl = Bbase< AImpl<T> >; ^ foo.cpp:11:29: note: previous declaration ‘template<class T> class BImpl’ template <typename T> class BImpl; ^ foo.cpp: In instantiation of ‘class AImpl<void>’: foo.cpp:28:4: required from here foo.cpp:18:28: error: invalid use of incomplete type ‘class BImpl<void>’ typename BImpl<T>::Ptr foo(); ^ foo.cpp:11:29: error: declaration of ‘class BImpl<void>’ template <typename T> class BImpl; ^ foo.cpp: In function ‘int main()’: foo.cpp:29:4: error: aggregate ‘B b’ has incomplete type and cannot be defined B b; ^ 转发声明为模板类,然后将其声明为别名类吗?

我最理想的是:

B

1 个答案:

答案 0 :(得分:1)

在第二个例子中,你有这个,它向前声明一个模板类:

template <typename T> class BImpl;

然后你尝试这样做,它声明了一个模板别名:

template <typename T>
using BImpl = Bbase< AImpl<T> >;

但是别名不是类 - 您不能使用别名来定义类。编译器告诉你:

foo.cpp:22:32: error: conflicting declaration of template ‘template<class T> using BImpl = Bbase<AImpl<T> >’
  

为什么第一个代码段有效?是第一种情况下的实施和后者的(重新)定义吗?

第一个代码段有效,因为它的格式正确;很简单,没有什么可以使它无法运作。在第二种情况下,您定义一个与类同名的别名,这是不允许的。

  

我可以将B转发声明为模板类,然后将其声明为别名类吗?

没有