派生类调用基类中的模板函数时的链接问题

发布于 2024-12-07 06:57:47 字数 479 浏览 0 评论 0原文

我在 base.h 中有一个类 Base,它有一个模板函数,

class Base {
 template <typename T> void test(T a);
}

该模板应该在 intdouble< 中读取/code> 类型,并且我有类 Derived,它派生自类 Base

我尝试在类 Derived 中调用函数测试,但出现链接器错误。

最后,我意识到如果在base.cpp中添加,

void test(int a);
void test(double a);

就不会有编译器错误。这个解决方案看起来很尴尬,有更好的解决方案吗?谢谢

I have a class Base in base.h, which has a template function

class Base {
 template <typename T> void test(T a);
}

this template is supposed to read in int or double type, and I have class Derived, which is derived from class Base

I tried to call function test in class Derived, but I have the linker error.

In the end, I realised that if in base.cpp, I add

void test(int a);
void test(double a);

there will be no compiler error. This solution seems awkward, is there a better solution? Thank you

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

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

发布评论

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

评论(3

南城追梦 2024-12-14 06:57:47

C++ 模板必须在使用它们的同一翻译单元(.CPP 文件加上所有包含的头文件)中定义(给出完整的函数体)。在头文件中,您所做的只是声明(给出函数的名称和签名)。结果是,当您包含 base.h 时,编译器看到的只是:

class Base {
  template <typename T> void test(T a);
}

This 声明但未定义该函数。要定义它,您必须包含一个函数体:

class Base {
  template <typename T> void test(T a)
  {
    // do something cool with a here
  }
}

之所以需要这样做,是因为 C++ 编译器会“根据需要”为模板生成代码。例如,如果您调用:

Base obj;
obj.test< int >( 1 );
obj.test< char >( 'c' );

编译器将根据 Base::test 模板生成两组机器代码,一组用于 int,一组用于 字符。这里的限制是 Base::test 模板的定义必须位于同一个翻译单元(.CPP 文件)中,否则编译器将不知道如何为每个版本构建机器代码Base::test 函数的。编译器一次仅对一个翻译单元进行操作,因此它不知道您是否定义了 Base::testBase::test< T > 在其他一些 CPP 文件中。它只能利用手头的东西来工作。

这与 C#、Java 和类似语言中泛型的工作方式有很大不同。就我个人而言,我喜欢将模板视为一个文本宏,编译器根据需要对其进行扩展。这迫使我记住,模板函数的完整主体需要包含在使用它的任何 CPP 文件中。

C++ templates must be defined (given a complete function body) in the same translation unit (.CPP file plus all included header files) where they are used. In your header file, all you have done is declared (given the name and signature of) the function. The result is that when you include base.h, all the compiler sees is:

class Base {
  template <typename T> void test(T a);
}

This declares but does not define the function. To define it, you must include a function body:

class Base {
  template <typename T> void test(T a)
  {
    // do something cool with a here
  }
}

The reason why this is required is that the C++ compiler generates code for templates on an "as-needed" basis. For example, if you call:

Base obj;
obj.test< int >( 1 );
obj.test< char >( 'c' );

The compiler will generate two sets of machine code based on the Base::test template, one for an int and one for a char. The limitation here is that the definition of the Base::test template must be in the same translation unit (.CPP file), or else the compiler will not know how to build the machine code for each version of the Base::test function. The compiler only operates on one translation unit at a time, so it has no idea whether or not you've defined Base::test< T > in some other CPP file. It can only work with what it has at hand.

This is quite different from the way generics work in C#, Java, and similar languages. Personally I like to think of templates as a text macro that gets expanded by the compiler as needed. That forces me to keep in mind that the complete body of the template function needs to be included in any CPP file where it is used.

流殇 2024-12-14 06:57:47

您必须完全定义模板函数 test 才能使用它。最简单的方法是将函数体写入 base.h 的标头中:

class Base {
 template <typename T> void test(T a)
 {
    ... function body here
 }
}

You must fully define the template function test before it can be used. The easiest way to do that is just to write your function body in the header in base.h:

class Base {
 template <typename T> void test(T a)
 {
    ... function body here
 }
}
黯淡〆 2024-12-14 06:57:47

如果您在基类中声明模板函数,这意味着它在编译时采用模板参数,但如果您尝试通过派生类(运行时实现)进行访问,则编译时的模板请求(您在运行时提供的模板请求是不可能的),主要是c ++不支持这个。

if you declare template function in base class which means it take the template argument at compile time but if u try to access through derived class which is runtime implementation so template request at compile time which ur providing at runtime is not possible ,and main thing c++ does not support this.

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