C++:任何在 main.cpp 中声明结构但在 header 中具有 class 模板的可能性

C++ : Any possibility to declare a struct in main.cpp but having a template with class in header

作为使用模板的 C++ 初学者,我有一个问题,如果它很荒谬,请原谅。

在 header 文件中有这样一个模板:

template <class T> class MyClass

是否可以像这样在main.cpp中定义一个结构:

struct CC;

struct CC
{

     MyClass (CC) p;
     CC() : p(0){}
}; 

或:

struct Foo {

    MyClass<struct Foo> bar;
    MyClass<std::string> text;
};

我对此很迷茫。对不起。

首先,模板是否在头文件中并不重要。编译器只看到预处理后的代码,此时没有文件。只是文字。

让我们考虑第一个示例的变体:

template< class T >
class MyClass
{
    int x;
};

struct CC
{

     MyClass<CC> m;
     CC() {}
}; 

auto main() -> int {}

这个编译很好,因为 MyClass 模板实际上并没有使用 CC 做任何事情,所以除了知道它是一个类型之外不需要任何其他知识。

但是假设它的大小被使用了。这需要 完整类型 。或者换句话说,完整类型大小已知的类型。

template< class T >
class MyClass
{
    char x[sizeof( T )];
};

struct CC
{

     MyClass<CC> m;
     CC() {}
}; 

auto main() -> int {}

这将无法编译,因为在使用 MyClass<CC> 的地方,CC 的大小尚不清楚。额外的数据成员,或者例如一个虚函数,可以稍后在 class 定义中定义。那会增加尺寸。


作为一个近似的反例,考虑第三个变体:

template< class T >
class MyClass
{
public:
    void foo()
    {
        char x[sizeof( T )];
    }
};

struct CC
{

     MyClass<CC> m;
     void use_foo() { m.foo(); }
     CC() {}
}; 

auto main() -> int {}

这编译正常,但为什么呢?显然这里的模板也需要完整的 CC 类型?

但是不,编译器将 class 中的成员函数定义视为已声明 inline 并在 class 之外定义,如下所示:

template< class T >
class MyClass
{
public:
    inline void foo();
};

template< class T >
void MyClass<T>::foo()
{
    char x[sizeof( T )];
}

struct CC
{

     MyClass<CC> m;
     inline void use_foo();
     CC() {}
}; 

void CC::use_foo() { m.foo(); }

auto main() -> int {}

从这里可以看出 MyClass 模板本身并不依赖于 CC.

的大小知识