Sve*_*end 0 c++ templates namespaces class header-files
我正在尝试编写一个C++库的问题.这是通常的设置,一个cpp文件,一个头文件.我希望头文件只显示要使用的部分(例如,我有一个抽象基类,我不想在头文件中).到目前为止,我只是处理一个文件(我认为这应该没有区别,因为包含是由预处理器完成的,它不关心任何事情).
您会注意到"头文件"分布在头部实现文件之前和之后的两个位置.
#include <stdio.h>
// lib.h
namespace foo {
template <class T> class A;
}
// lib.cpp
namespace foo {
template <class T> class A {
private:
T i;
public:
A(T i) {
this->i = i;
}
T returnT() {
return i;
}
};
};
// lib.h
namespace foo {
template <class T> T A<T>::returnT();
}
// foo.cpp
void main() {
foo::A<int> a = foo::A<int>(42);
printf("a = %d",a.returnT());
}
Run Code Online (Sandbox Code Playgroud)
所以,当然,我希望我的头文件只包含
namespace foo {
template <class T> class A;
template <class T> T A<T>::returnT();
}
Run Code Online (Sandbox Code Playgroud)
但是我的编译器不喜欢这个(它抱怨它returnT不是成员foo::A<T>.我不想把类声明本身放在标题中的原因是它会(根据我的理解),包含所有的私有和类似的东西,我想隐藏.
也许只是我,但是下面的头文件似乎"糟糕",至少作为"接口规范".它暴露了一些Alib的用户不需要知道的内部结构.
// lib.h
namespace foo {
template <class T> class A {
private:
int i;
public:
A(T);
T returnT();
};
}
// lib.cpp
namespace foo {
template <class T> A<T>::A(T i) {
this->i = i;
}
template <class T> T A<T>::returnT() {
return i;
}
};
Run Code Online (Sandbox Code Playgroud)
这是接受的做法吗?如果可能的话,我想要一个更抽象的头文件.
您不能将模板的定义与其声明分开.他们都必须一起进入头文件.
因为"为什么?" 我建议阅读"为什么我不能将模板类的定义与其声明分开并将其放在.cpp文件中?" .
我可能误读了你的问题.要解决可能也是您的问题,这是无效的:
namespace foo {
template <class T> class A;
template <class T> T A<T>::returnT();
}
Run Code Online (Sandbox Code Playgroud)
由于这是无效的相同原因,它无效:
namespace foo {
class A;
int A::returnT();
}
Run Code Online (Sandbox Code Playgroud)
必须在类的定义中声明成员函数.