派生类调用基类中的模板函数时的链接问题
我在 base.h
中有一个类 Base,它有一个模板函数,
class Base {
template <typename T> void test(T a);
}
该模板应该在 int
或 double< 中读取/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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
C++ 模板必须在使用它们的同一翻译单元(.CPP 文件加上所有包含的头文件)中定义(给出完整的函数体)。在头文件中,您所做的只是声明(给出函数的名称和签名)。结果是,当您包含
base.h
时,编译器看到的只是:This 声明但未定义该函数。要定义它,您必须包含一个函数体:
之所以需要这样做,是因为 C++ 编译器会“根据需要”为模板生成代码。例如,如果您调用:
编译器将根据
Base::test
模板生成两组机器代码,一组用于int
,一组用于字符
。这里的限制是Base::test
模板的定义必须位于同一个翻译单元(.CPP 文件)中,否则编译器将不知道如何为每个版本构建机器代码Base::test
函数的。编译器一次仅对一个翻译单元进行操作,因此它不知道您是否定义了Base::test
Base::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:This declares but does not define the function. To define it, you must include a function body:
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:
The compiler will generate two sets of machine code based on the
Base::test
template, one for anint
and one for achar
. The limitation here is that the definition of theBase::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 theBase::test
function. The compiler only operates on one translation unit at a time, so it has no idea whether or not you've definedBase::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.
您必须完全定义模板函数
test
才能使用它。最简单的方法是将函数体写入base.h
的标头中: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 inbase.h
:如果您在基类中声明模板函数,这意味着它在编译时采用模板参数,但如果您尝试通过派生类(运行时实现)进行访问,则编译时的模板请求(您在运行时提供的模板请求是不可能的),主要是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.