【发布时间】:2017-05-14 22:05:58
【问题描述】:
当我将模板函数作为基类的模板参数传递时,链接器抱怨它无法链接该函数:
#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
我错过了什么?
【问题讨论】:
-
这个问题似乎是一个 gcc 错误:它使用 clang 和 icc 编译和链接正常。顺便说一句,名称 identity() 通常用于结果与参数相同的转换。
-
@DietmarKühl 好吧,
identity<X>()返回X。 :-) -
解决方法:
class Derived : public Base<static_cast<int(*)()>(identity<10>) >。 live demo -
@melpomene:当然。但是,模板参数似乎更像是一个索引(如 fi())而不是函数参数。
标签: c++ templates inheritance gcc template-inheritance