链接器错误与C ++函数模板实例化(模板实例化类的成员函数)

时间:2014-01-19 11:46:26

标签: c++ templates linker

我有很多现有的C ++代码,其模板类在.cpp文件中有实现。 我想在一个这样的类中添加模板函数。我的问题是我不能使编译器实例化功能模板。

我创建了一个展示问题的剥离示例。我想添加成员函数convert(),并使用自己的模板参数LenNew

template <typename Number, int Len>
class MyClass {
public:
    // the function I'm trying to add
    template <int LenNew>
    MyClass<Number, LenNew> convert();

    // other methods I want to keep this way
    void function(); // implemented in .cpp file

private:
    Number n[Len];
};

在现有设置中,.cpp文件实现方法并实例化类模板:

template <typename Number, int Len>
void MyClass<Number, Len>::function()
{
    // implementation
}

// instantiate template-class with specific template parameters
template class MyClass<double, 1>;

所以我添加了新成员函数的实现,尝试实例化模板,这似乎不起作用:

template <typename Number, int Len>
template <int LenNew>
MyClass<Number, LenNew> MyClass<Number, Len>::convert()
{
    // implement...
}

// try instantiate
template<> template<> MyClass<double, 2> MyClass<double, 1>::convert<2>();

它编译得很好,但是当我尝试使用来自不同.cpp文件的convert()时,我得到一个未定义的引用:

main.cpp:(.text+0x1c): undefined reference to `MyClass<double, 2> MyClass<double, 1>::convert<2>()'

以下是演示程序的要点https://gist.github.com/md2k7/8503385

抱歉,似乎有很多非常相似的问题,但我仍然无法理解错误。

2 个答案:

答案 0 :(得分:1)

据我所知,您希望显式实例化类模板的方法。而这种方法也是模板。你正试图使用​​这样的结构:

template<> template<> MyClass<double, 2> MyClass<double, 1>::convert<2>();

但这种结构意味着完全不同的东西。它是非专用类模板的显式专用方法模板的声明。你的案子有正确的结构:

template MyClass<double, 2> MyClass<double, 1>::convert<2>();

但是你还应该为MyClass类模板的额外显式实例化添加一条指令:

template class MyClass<double, 2>;

如果您真的想在代码中使用convert方法的结果。

答案 1 :(得分:0)

我找到了解决方法 - 专门化新成员函数convert(),明确地将正确的版本放在myclass.cpp中:

template <>
template <>
MyClass<double, 2> MyClass<double, 1>::convert()
{
    // implementation...
}

这可能导致convert()的一些重复代码,因为MyClass<Number, Len>的每个版本都需要它(但对我来说,目前只有2个版本需要具有此功能),但旧的代码可以保持不变。