2014-01-19 48 views
1

夥計們,這是我在StackOverflow中的第一個問題,所以如果出現任何錯誤,請原諒我。
我正在寫一個包含2個源文件和3個頭文件的小項目。在C++中多重定義的解決方案

// some_template_functions.h

#ifndef SOME_TEMPLATE_FUNCTION_H 
#define SOME_TEMPLATE_FUNCTION_H 

template <typename T> 
int getvalue(string line, string key, T & val) 
{ 
    // method to get value (all the types except string) from line using key 
} 
template <> 
int getvalue<string>(string line, string key, string &val) 
{ 
    // method to get some string from line using key, similar to getvale<int> 
    // but with slight difference to handle some special characters 
} 

#endif 

//myclass.h

#ifndef MYCLASS_H 
#define MYCLASS_H 
#include "some_template_functions.h" 

class MYCLASS 
{ 
    //declarations of constructors, member functions and members 
    double member_double; 
    string member_string; 
} 

#endif 

//myclass.cpp

#include "myclass.h" 

MYCLASS:MYCLASS() 
{ 
    // for each member 
    // using "getvalue" defined in "SOME_TEMPLATE_FUNCTION.H" to get the values 
    getvalue(line, key, member_double); 
    getvalue(line, key, member_string); 
} 

//main.cpp

#include "myclass.h" 
#include "some_template_functions.h" 

int main() 
{ 
    myclass A; 
    int some_value; 
    getvalue(line, key, value); 
    return 0; 
} 

我沒有問題,編譯main.o和myclass.o但它只是當我試圖將兩個目標文件鏈接我得到錯誤信息,如:

 myclass.cpp: multiple definition of int getvalue<std::basic_string><char, std::char_traits<char>, ...> and etc.  
    /tmp/cc22zEow.o:main.cpp: first defined here  
    collect2: ld returned 1 exit status  

我知道其中的原因可能是因爲我包括myclass.h和main.cpp中的「some_template_function.h」,每個myclass.o和main.o都會有自己定義的導致問題的getvalue。如果我改變

#include "some_template_functions.h" 

#ifndef SOME_TEMPLATE_FUNCTIONS_H 
#define SOME_TEMPLATE_FUNCTIONS_H 
#endif 

MYCLASS的構造並不goint工作。

我打算在將來擴展「some_template_functions.h」及其.cpp文件,所以如果可能的話,我想保持它們與其他文件分開。因爲我聲明函數「getvalue」的方式,所以我試圖將它的定義移動到.cpp文件中,這對我來說並不適合。

我試着解決這個問題好幾天,但自從我剛剛開始學習C++到目前爲止,我無法得到這個權利。所以請,任何建議將不勝感激!提前致謝!

+0

getvalue在這裏被多次定義。鏈接器無法識別它應該使用哪個函數。您可以重載函數以明確區分鏈接器要調用的函數。 – Sumeet

+0

有趣。這些功能是否具有靜態功能?如果不是,則在模板參數列表之後但在返回值之前放置一個'inline'。即'template inline int getvalue(string line,string key,T&val)'。但是,無論你的擴張沒有得到解決,它都會讓我惱火。 – WhozCraig

+0

@WhozCraig:「內聯」實際工作!你能解釋一下更多爲什麼?而且我對「靜態」不是很熟悉,那將如何工作?我是否聲明getvalue爲'template static int getvalue(string line,string key,T&val)'? – user3210923

回答

2

getvalue<std::string>(...)的專業化不是一個模板,因此,不隱式地inline。如果你想在一個頭文件中定義這個函數,例如,因爲它接近平凡,應該是inlined,你需要明確標記爲inline。如果函數做了不重要的事情,那麼可能只需要在頭文件中聲明特殊化並將其定義在合適的翻譯單元中即可。