对模板基类的成员函数的未定义引用 [英] Undefined reference to member function of template base class

查看:598
本文介绍了对模板基类的成员函数的未定义引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

myclass.h:

myclass.h :

template <class T>
struct S {
    void f();
};

struct MyClass : public S<int>
{
    void g();
};

myclass.cpp:

myclass.cpp :

#include "myclass.h"
#include <iostream>

template <class T>
void S<T>::f()
{
    std::cout << "f()\n";
    /* some code here that could not be in header */
}

void MyClass::g()
{
    std::cout << "g()\n";
}

main.cpp:

#include "myclass.h"

int main()
{
    MyClass m;
    m.g();
    m.f(); // problem here
}

我有链接器错误:


未定义引用`S :: f()'

undefined reference to `S::f()'

我可以解决这个问题,而不将S :: f()的实现转移到头文件?
为什么当我声明一个从完全专门的模板基类派生的MyClass时,S :: f()不会实例化?

Can I solve this issue without transferring implementation of S::f() to header file? Why S::f() not instantiated when I declare a MyClass derived from full specialized template base class?

推荐答案


为什么当我声明一个从完全专门的模板基类派生的MyClass时,S :: f()没有实例化?

Why S::f() not instantiated when I declare a MyClass derived from full specialized template base class?

因为您的myclass.cpp不使用该模板,并像所有未使用的模板在翻译单元,它们在生成的代码没有。如果 MyClass :: g()使用 S :: f()你会把代码和生活是好的。但你不行,所以你必须以另一种方式拉它...

Because your myclass.cpp makes no use of that template, and like all unused templates in translation units, they amount to nothing in the produced code. The derivation is all well and good, and if MyClass::g() used S<T>::f() you would pull in that code and life would be good. But you don't, so you have to pull it in another way...

你应该能够通过显式实例化来做到这一点。请注意以下对.cpp文件的补充:

You should be able to do this with explicit instantiation. Note the following addition to your .cpp file:

#include "myclass.h"
#include <iostream>

template <class T>
void S<T>::f()
{
    std::cout << "f()\n";
}

void MyClass::g()
{
    std::cout << "g()\n";
}

template struct S<int>; // ADDED

但是请注意。这将只有当唯一的用途是 S< int> 时才有效。额外的扩展将需要显式实例化的附加条目。

Be warned, however. This will only work if the only usage is S<int>. Additional expansions would need additional entries of explicit instantiations.

您也可以使用直接专业化功能,例如更改.cpp,只需执行以下操作:

You could also do it with direct specialization, such as changing your .cpp to just do this:

#include "MyClass.h"
#include <iostream>

template <>
void S<int>::f()
{
    std::cout << "f()\n";
}

void MyClass::g()
{
    std::cout << "g()\n";
}

但是这在我看来会有限制,需要自己的专业化。

but that would be rather limiting in my mind, as each additional type you add would need its own specialization.

无论如何,祝你好运。

这篇关于对模板基类的成员函数的未定义引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆