2016-08-05 11 views
6

Я использую этот класс с - все, кроме одного - функции члена-шаблона, которые будут использоваться в проекте с несколькими исходными файлами, которые связаны с компиляцией. Тип шаблона неизвестен и может принимать к нему любой тип. В этом случае у меня есть два исходных файла, которые используют класс, поэтому заголовочный файл с объявлением и определением класса имеет #include: ed в обоих исходных файлах. Затем я получаю ошибку «множественное определение» в объявлении функции члена без шаблона класса. Я предполагаю, что это потому, что он определяется дважды во время процесса связывания, поскольку оба исходных файла имеют определение функции-члена, отличного от шаблона. Представьте, что сценарий, не относящийся к смыслу ниже:C++ :: #include: заголовок заголовка шаблона шаблона в нескольких исходных файлах?

Примечание. Предположим, что все файлы включают охрану, а iostream - #include: ed везде, где это необходимо.

foo.hpp

class foo 
{ 
public: 
    template <typename X> 
    void f(X); 

    void ff(); 
}; 

#include "foo.tpp" 

foo.tpp

template <typename X> 
void foo::f(X val) 
{ 
    cout << val; 
} 

void foo::ff() // multiple definitions 
{ 
    cout << sizeof(*this); 
} 

main2.cpp

#include "foo.hpp" 

main.cpp

#include "foo.hpp" 

int main() 
{ 
    return 0; 
} 

Добавление встроенного ключевого слова в определении функции, кажется, решить эту ошибку, хотя я не хочу использовать его, потому что у меня есть другие функции-члены, не шаблон, страдающих такой же вопрос которые намного больше и упоминаются в нескольких частях кода. Есть ли какой-нибудь рабочий или действительный способ сделать то, что я пытаюсь сделать? Заранее спасибо!

+1

Для того, что это стоит, все шаблонные функции уже неявно «встроены», если они полностью не специализированы. –

+0

Ouch. Определенно стоит упомянуть! Я буду помнить об этом. Большое спасибо за вклад. –

+1

Добро пожаловать. Это связано с тем, что шаблонный код должен быть видимым в любой единицы перевода, которая его использует, поэтому компилятор может создать из него фактический код, в свою очередь, означает, что шаблонный код должен быть 'inline', чтобы допускать несколько идентичных определений. Полностью специализированная шаблонная функция рассматривается как нормальная функция, хотя, поскольку ей не нужно заполнять какие-либо параметры шаблона, и, следовательно, ее можно рассматривать как фактический код (позволяющий привязываться к нему, в отличие от неспециализированных шаблонных функций). –

ответ

6

Создайте третий файл foo.cpp для определения функций без шаблона, которые не объявлены как inline. Класс не является шаблоном, поэтому вам не нужно определять все его функции-члены в заголовке, только шаблонные (или maybe not).

+1

Простые решения всегда скрываются за углом и много раз я их пропускаю. Ни в коем случае я бы не подумал об этом, и этот вопрос прослушивал меня неделю, пока я не решил отказаться от своей гордости и спросить. Очень умное решение. Наверное, я понял, что делать дальше. Благодаря тонну! –

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

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