以下是我正在处理的文件:
class.h
#include <vector>
using std::vector;
template<class T>
class test {
private:
vector<T> data;
public:
typedef vector<T> vt;
typedef typename vt::iterator it;
test() {
}
;
it find(T x);
}
和class.cpp
#include "class.h"
it test::find(T x) {
return find(data.begin(), data.end(), x);
}
如果我将find的实现放在类声明中,代码就可以工作。
但是,当我将实现与类分开时,编译器会报告错误“测试前的预期初始化程序”。
如何解决?该问题是否与typedef / typename的范围有关?
抱歉我的英语不好,这是我的第二语言。
请指出我的代码中的任何错误以及我的英文
感谢您的帮助。:D
答案 0 :(得分:0)
现在C ++中的模板违反了这个原则,bcoz C ++是一种编译语言。编译器在编译期间生成所有需要的代码。现在要遵守OOP,我们最终会得到脆弱的模板,这些模板本质上不是100%通用的。
保持声明和定义分开(共享实施)
如果您只是想保持干净整洁,那么您可以将实施文件包含在另一个标题中。我认为它应该是头文件,因为这符合我们共享.h文件的基本约定,我们保持.cc文件不被共享(直到你共享代码本身)。这是文件的外观。
<强> foo.h中强>
这是包含foo_impl.h
的简单文件。
#ifndef FOO_H
#define FOO_H
template <class T>
class Foo {
public:
Foo (T);
T get();
private:
T data;
};
#include "foo_impl.h"
#endif
<强> foo_impl.h 强>
这个与规范略有不同。这里我们不守护头文件内容。相反,如果某个人直接包含foo_impl.h
(在我们的例子中没有意义),我们会引发错误。
#ifndef FOO_H
#error 'foo_impl.h' is not supposed to be included directly. Include 'foo.h' instead.
#endif
template <class T>
Foo <T> :: Foo (T stuff) {
data = stuff;
}
template <class T>
T Foo <T> :: get () {
return data;
}
现在,如果有人试图直接包含foo_impl.h
,则会收到如下错误:
foo_impl.h:2:2: error: #error 'foo_impl.h' is not supposed to be included directly. Include 'foo.h' instead.
优点:
CONS:
保持声明和定义分开(不共享实施)
为了不共享模板代码,您必须在.cc / .cpp文件中定义模板可以使用的所有可能数据类型,如:
template class foo< int >;
template class foo< double >;
优点:
CONS:
答案 1 :(得分:0)
当编译器看到it
时,它还不知道您的意思是test<T>::it
。所以你必须告诉它:
template<class T> typename test<T>::it test<T>::find(T x) {
// The following line doesn't compile, but that's another issue:
// return find(data.begin(), data.end(), x);
}
有关正在运行的计划,请参阅http://ideone.com/Rtho2。