模板不在范围内

发布于 2024-10-12 10:15:09 字数 530 浏览 2 评论 0原文

在“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 中?

谢谢...

Got this in "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

Now with this simple test :

#include "char.h"


void test(Char<TChar> &oo)
{
  //...
}


int main(int argc, char *argv[])
{
  Char<80> gg;

  return 0;
}

I get with gcc :
TChar was not declared in that scope !?
I don't understand, the declaration is in the .h ??

Thanks...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱殇璃 2024-10-19 10:15:09

模板类的完整实现必须位于该模板类的标头中(否则您可能会收到链接器错误)。
编译器需要访问整个模板定义(而不仅仅是签名),以便为模板的每个实例化生成代码,因此您需要将函数的定义移至标头。 (包容模型)。

您已正确放置定义。 :-)

但是,在 void test(Char&oo) 中,编译器不知道 TChar 是什么。尝试在定义上方添加 template

template <unsigned int TChar>
void test(Char<TChar> &oo){
  // ... stuff
}

The full implementation of a template class must be in that template class's header (otherwise you are likely to get a linker error).
The compiler needs to have access to the entire template definition (not just the signature) in order to generate code for each instantiation of the template, so you need to move the definitions of the functions to your header. (Inclusion Model).

You have placed the definition correctly. :-)

However in void test(Char<TChar> &oo) the compiler doesn't know what TChar is. Try adding template <unsigned int TChar> above the definition

template <unsigned int TChar>
void test(Char<TChar> &oo){
  // ... stuff
}
灰色世界里的红玫瑰 2024-10-19 10:15:09

您似乎对模板类是什么感到困惑。当您编写时:

template <unsigned int TChar>
class Char
{
    /*  ...  */
}; 

您正在告诉编译器如何生成名为 Char 的类。每次您在代码中的某个位置使用 Char<1>Char<2>... 以及不同的参数时,编译器都会为您创建一个新类。

名称 TChar 仅表示作为类型名称的一部分给出的值,并且仅在类模板内有效。

这意味着,当您编写 Char<80> 时,编译器会查看他是否已经具有该类型 - 但实际上没有,因此他会创建一个名为 Char<80>< 的新类。 /code> 基于您的模板。这就是为什么您不能编写接受任何 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) { /* ... */ }

You seem to be confused about what template class is. When you write:

template <unsigned int TChar>
class Char
{
    /*  ...  */
}; 

You're telling the compiler how to generate classes named as Char<somenumber>. Every time you use Char<1>, Char<2>, ... with different parameters somewhere in your code, the compiler will create a new class for you.

The name TChar only represents the value that is to be given as the part of the type name and is valid only inside your class template.

This means that when you write Char<80> the compiler looks if he already has that type - which he doesn't, so he goes and creates a new class named Char<80> based on your template. That's why you can't write a function that takes any Char because Char<80> and Char<81> are different types.

What others are suggesting is that you can turn your function into a function template.

// compiler can't know what value should be used here
// it expects an unsigned int inside <>
void test(Char<TChar> &oo)
{
  //...
}

With function templates it works the same as with classes.

template<unsigned int TChar>
void test(Char<TChar> &oo)
{
  //...
}

Now when you write

Char<80> gg;
test(gg);

The compiler looks at the type of gg, sees that it can match it with your function template, creates a function with TChar evaluated as 80 and all works out nicely :)

To be precise, the call to your function should look like this:

test<80>(gg);

but you don't have to say this explicitly, because the compiler has enough information from the type of gg to work that all out for you.


If you want to pass Char instantiations to non-templated functions, you can achieve this with polymorphism like this:

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) { /* ... */ }
無心 2024-10-19 10:15:09
void test(Char<TChar> &oo)
{
  //...
}

对于要编译的此函数,TChar 未定义。文件 char.h 未定义 TChar

void test(Char<TChar> &oo)
{
  //...
}

TChar is undefined for this function to be compiled. The file char.h doesn't define TChar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文