C++ 错误消息";作为模板参数传递的对模板函数的未定义引用";
当我将模板函数作为基类的模板参数传递时,链接器会抱怨它无法链接该函数:C++ 错误消息";作为模板参数传递的对模板函数的未定义引用";,c++,templates,inheritance,gcc,template-inheritance,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() {
#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;
}
template<int I>
struct identity {
operator int() { return I; }
};
template<typename fn>
class Base {
public:
int f() {
return fn();
}
};
#包括
模板内联int-identity(){return I;}
//模板内联int-identity(){return 20;}
模板
阶级基础{
公众:
int f(){
返回fn();
}
};
模板
派生类:公共基{
公众:
int f2(){
返回f();
}
};
int main(int argc,字符**argv){
衍生o;
printf(“结果:%d\n”,o.f2());
返回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
$g++-o test2 test2.cpp&&./test2
/tmp/ccahIuzY.o:在函数'Base::f()'中:
test2.cpp:(.text._ZN4BaseIXadL_Z8identityILi10EEivEEE1fEv[_ZN4BaseIXadL_Z8identityILi10EEivEEE1fEv]+0xd):未定义对“int identity()”的引用
collect2:错误:ld返回了1个退出状态
如果我注释掉专门化,那么代码将按照预期编译和链接。此外,如果我从Base
继承而不是从Base
继承,那么代码将按照我的预期工作
试试这里:
我错过了什么?将其提升到typedef中会使其编译,即
typedef Base< identity<10> > base10;
typedef Basebase10;
我不太清楚为什么在类定义中直接这样做不起作用
问题似乎是gcc错误:代码编译并链接到clang、icc和EDG前端。不改变任何用途的潜在解决办法是使用类模板
identity
,而不是函数:
#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;
}
template<int I>
struct identity {
operator int() { return I; }
};
template<typename fn>
class Base {
public:
int f() {
return fn();
}
};
模板
结构标识{
运算符int(){return I;}
};
模板
阶级基础{
公众:
int f(){
返回fn();
}
};
这个问题似乎是一个gcc错误:它使用clang和icc编译并链接OK。顺便说一句,名称identity()通常用于转换,其结果与参数相同。@DietmarKühl那么,identity()
返回X
:-)解决方法:派生类:public Base
@梅尔波梅:当然。但是,模板参数似乎更像一个索引(如fi()),而不是函数参数。不使函数模板内联
也可以工作。链接器不应该删除重复的模板实例化吗?