2014-09-22 5 views
0

Я использую EnumParser из here Он отлично компилируется в VC++, но с использованием GCC у меня есть такая ошибка:НКУ - ошибка множественного определения при определении шаблона (VC++ отлично)

./Terminator.o: In function `EnumParser<FieldType>::EnumParser()': 
Terminator.cpp:(.text+0x960): multiple definition of `EnumParser<FieldType>::EnumParser()' 
./MicexGate.o:MicexGate.cpp:(.text+0xd0): first defined here 
./Terminator.o: In function `EnumParser<FieldType>::EnumParser()': 
Terminator.cpp:(.text+0x960): multiple definition of `EnumParser<FieldType>::EnumParser()' 
./MicexGate.o:MicexGate.cpp:(.text+0xd0): first defined here 
./Terminator.o: In function `EnumParser<FieldsetName>::EnumParser()': 

кажется EnumParser<FieldType>::EnumParser() появился в обоих MicexGate.o и Terminator.o, и это проблема. Но я не знаю, почему это ошибка и как ее исправить.

В моей программе я определяю этот EnumParser только один раз в файле .cpp в файле MicexGate static lib project. Terminator зависит от MicexGate, вероятно, именно поэтому окончательно EnumParser определил дважды. Это, как я определяю EnumParser<FieldType>:

#include "FieldsConverter.h" 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/xml_parser.hpp> 
#include <iostream> 
#include "ByteArrayReader.h" 
#include "Utils.h" 
#include "CommonsMicexBridge.h" 
#include "InstrumentsStorage.h" 
#include <boost/algorithm/string.hpp> 

template<> EnumParser<FieldType>::EnumParser() 
{ 
    enumMap["Char"] = Char; 
    enumMap["Integer"] = Integer; 
    enumMap["Long"] = Long; 
    enumMap["Fixed"] = Fixed; 
    enumMap["Price"] = Price; 
    enumMap["Date"] = Date; 
    enumMap["Time"] = Time; 
} 

Как я могу исправить мою проблему?

+1

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

ответ

1

Я предполагаю, что вы не объявили явную специализацию в заголовке, включенный в каждый файл, который использует специализацию:

template<> EnumParser<FieldType>::EnumParser(); 

Без этой декларации, компилятор не знает, что явная специализация существует, поэтому будет создавать экземпляр неявной специализации из общего шаблона, если он нужен. Теперь у вас есть два определения, в результате (надеюсь) в ошибке ссылки.

В качестве альтернативы, как и для любой функции, вы можете определить ее в заголовке до тех пор, пока вы объявите ее inline, чтобы разрешить определения в нескольких единицах перевода.

+0

Я попытался перейти в файл .h и добавить 'inline', но это не поможет. Я попытаюсь добавить явное объявление в файл .h и реализацию .cpp – javapowered

+0

Я попытался выделить: определение в .h-файле в файле .cpp. По какой-то причине это не работает в моем случае. – javapowered

+0

@javapowered: Вы имеете в виду, что вы пытались с помощью * объявления * в файле .h' (как в моем ответе) и * definition * (aka impelementation) в '.cpp' файле (как в вашем вопросе)? Это должно работать, если вы включаете заголовок везде, где требуется специализация. Если нет, пожалуйста, покажите нам, что вы пробовали (желательно как минимальный, но полный тестовый пример), и что пошло не так. –

1

Шаблоны должны быть в заголовках, а не в .cpp-файлах.

+1

Хотя это правда, оно не объясняет ошибки, о которых спрашивает ОП. –

+1

Это явная специализация, а не определение шаблона. Он подчиняется Правилу Единого определения точно так же, как регулярная функция; поэтому нужно либо перейти в исходный файл, либо объявить 'inline'. –

+0

Первоначально он был в файле '.h', но у меня была такая же ошибка компиляции. Я переместил его в .cpp, надеюсь, что это может помочь, но это не так. – javapowered