在“char.h”中得到了这个
#ifndef _CHAR_H_
#define _CHAR_H_
#include <stdio.h>
template <unsigned int TChar>
class Char
{
public:
Char(){ *m_data=0; m_len=-1; }
private:
char m_data[TChar+1];
int m_len;
};
#endif
现在通过这个简单的测试:
#include "char.h"
void test(Char<TChar> &oo)
{
//...
}
int main(int argc, char *argv[])
{
Char<80> gg;
return 0;
}
我用gcc: TChar未在该范围内宣布! 我不明白,声明是在.h ??
...谢谢
答案 0 :(得分:1)
模板类的完整实现必须位于该模板类的标头中(否则您可能会收到链接器错误)。 编译器需要访问整个模板定义(而不仅仅是签名)才能为模板的每个实例化生成代码,因此您需要将函数的定义移动到标题中。 (包含模型)。
您已正确放置了定义。 : - )
但是在void test(Char<TChar> &oo)
中,编译器不知道TChar
是什么。尝试在定义
template <unsigned int TChar>
template <unsigned int TChar>
void test(Char<TChar> &oo){
// ... stuff
}
答案 1 :(得分:1)
您似乎对模板类是什么感到困惑。当你写:
template <unsigned int TChar>
class Char
{
/* ... */
};
您告诉编译器如何生成名为Char<somenumber>
的类。每次在代码中的某处使用Char<1>
,Char<2>
,...时,编译器都会为您创建一个新类。
名称TChar
仅表示作为类型名称的一部分提供的值,仅在您的类模板中有效。
这意味着当你编写Char<80>
时,编译器会查看他是否已经拥有该类型 - 他没有,所以他会根据你的模板创建一个名为Char<80>
的新类。这就是为什么你不能写一个带任何Char 的函数,因为Char<80>
和Char<81>
是不同的类型。
其他人的建议是,您可以将您的功能转换为功能模板。
// compiler can't know what value should be used here
// it expects an unsigned int inside <>
void test(Char<TChar> &oo)
{
//...
}
使用功能模板,它与类相同。
template<unsigned int TChar>
void test(Char<TChar> &oo)
{
//...
}
现在写的时候
Char<80> gg;
test(gg);
编译器查看gg的类型,发现它可以与你的函数模板匹配,创建一个TChar
评估为80的函数,并且所有函数都很好用:)
确切地说,对函数的调用应如下所示:
test<80>(gg);
但你不必明确地说明这一点,因为编译器有足够的gg
类型的信息来为你工作。
如果要将Char
实例化传递给非模板化函数,可以使用这样的多态实现:
class CharBase {
public:
virtual char get(int index) = 0;
virtual ~CharBase() {} // virtual destructor is strongly recommended
};
template<unsigned int CharT>
class Char : public CharBase {
public:
char get(int index) { return m_data[index]; }
/* ... */
};
void test(CharBase &myChar) { /* ... */ }
答案 2 :(得分:0)
void test(Char<TChar> &oo)
{
//...
}
未定义 TChar
以便编译此函数。文件char.h没有定义TChar
。