Подтвердить что ты не робот

Сообщение об ошибке "undefined ссылка на функцию шаблона, переданную как параметр шаблона"

Когда я передаю функцию шаблона в качестве параметра шаблона базового класса, компоновщик жалуется, что он не может связать функцию:

#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

Что мне не хватает?

4b9b3361

Ответ 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();
    }
};

Ответ 2

Поднимая его в typedef, он компилируется, т.е.

typedef Base< identity<10> > base10;

Я не совсем уверен, почему это делается прямо в определении класса, не работает.

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