2016-12-30 10 views
22

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

#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

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

+3

Эта проблема кажется GCC ошибка: он собирает и связывает OK с помощью лязг и КМК. Кстати, имя _identity() _ обычно используется для преобразования, где результат идентичен аргументу. –

+0

@ DietmarKühl Ну, 'identity ()' возвращает 'X'. :-) – melpomene

+2

Обходной путь: 'class Производный: public Base (identity <10>)>'. [live demo] (http://melpon.org/wandbox/permlink/E4aRHqcZaac7vd3C) –

ответ

19

Кажется, что проблема является GCC ошибка: код компилируется и с лязгом, КВК, и EDG интерфейсе. Потенциальный обходным не меняя каких-либо целей будет использование шаблона класса identity вместо функции:

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

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

Не может также работать шаблон функции 'inline'. Разве линкер не должен удалять повторяющиеся экземпляры шаблонов? – Etherealone

9

Подъемное его в ЬурейеЕ делает его компиляции, т.е.

typedef Base< identity<10> > base10; 

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^