错误消息“作为模板参数传递的模板函数的未定义引用”

时间:2016-12-30 15:58:17

标签: c++ templates inheritance gcc template-inheritance

当我将模板函数作为基类的模板参数传递时,链接器会抱怨它无法链接该函数:

#include <stdio.h>

template<int I> inline int identity() {return I;}
//template<> inline int identity<10>() {return 20;}

template<int (*fn)()>
class Base {
public:
    int f() {
        return fn();
    }
};

template<int Val>
class Derived : public Base<identity<10> > {
public:
    int f2() {
        return f();
    }
};

int main(int argc, char **argv) {
    Derived<10> o;
    printf("result: %d\n", o.f2());
    return 0;
}

结果:

$ g++ -o test2 test2.cpp && ./test2
/tmp/ccahIuzY.o: In function `Base<&(int identity<10>())>::f()':
test2.cpp:(.text._ZN4BaseIXadL_Z8identityILi10EEivEEE1fEv[_ZN4BaseIXadL_Z8identityILi10EEivEEE1fEv]+0xd): undefined reference to `int identity<10>()'
collect2: error: ld returned 1 exit status

如果我注释掉了专业化,那么代码会按预期编译和链接。另外,如果我继承自Base<identity<Val> >而不是Base<identity<10> >,则代码可以正常运行。

在此尝试:http://coliru.stacked-crooked.com/a/9fd1c3aae847aaf7

我想念什么?

2 个答案:

答案 0 :(得分:19)

似乎问题是gcc错误:代码编译并链接clang,icc和EDG前端。不改变任何用途的潜在解决方法是使用类模板template<int I> struct identity { operator int() { return I; } }; template<typename fn> class Base { public: int f() { return fn(); } }; 而不是函数:

A

答案 1 :(得分:9)

将其提升为typedef会使其编译,即

typedef Base< identity<10> > base10;

我不太确定为什么在课堂定义中直接做这件事并不起作用。

http://coliru.stacked-crooked.com/a/f00b4f4d1c43c2b0