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
.
的大小知识
作为使用模板的 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
.