根据this question的建议,我使用了后期模板实例化来解耦两个类testTemplateBuilder
和A
,它们互相引用:
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
答案 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
转发声明为模板类,然后将其声明为别名类吗?
没有