【问题标题】:Error message "undefined reference to template function passed as template parameter"错误消息“对模板函数的未定义引用作为模板参数传递”
【发布时间】: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&lt;identity&lt;Val&gt; &gt; 继承而不是Base&lt;identity&lt;10&gt; &gt;,则代码将按预期工作。

在这里试试:http://coliru.stacked-crooked.com/a/9fd1c3aae847aaf7

我错过了什么?

【问题讨论】:

  • 这个问题似乎是一个 gcc 错误:它使用 clang 和 icc 编译和链接正常。顺便说一句,名称 identity() 通常用于结果与参数相同的转换。
  • @DietmarKühl 好吧,identity&lt;X&gt;() 返回X。 :-)
  • 解决方法:class Derived : public Base&lt;static_cast&lt;int(*)()&gt;(identity&lt;10&gt;) &gt;live demo
  • @melpomene:当然。但是,模板参数似乎更像是一个索引(如 fi())而不是函数参数。

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


【解决方案1】:

问题似乎是 gcc 错误:代码编译并与 clang、icc 和 EDG 前端链接。不改变任何用途的潜在解决方法是使用类模板identity 而不是函数:

template<int I>
struct identity {
    operator int() { return I; }
};

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

【讨论】:

  • 不制作函数模板inline也可以。链接器不应该删除重复的模板实例吗?
【解决方案2】:

将其提升为 typedef 使其可以编译,即

typedef Base< identity<10> > base10;

我不太清楚为什么直接在类定义中这样做是行不通的。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    相关资源
    最近更新 更多