2016-06-29 30 views
0

我有以下類模板,它有一個成員變量,其類型由模板參數確定。我想在構造函數中初始化這個成員的值,它只需要std::string。因此,我的問題是我需要將std::string轉換爲幾種類型中的任何一種(int,double,bool,string)。我不認爲我可以只專注於構造函數,我不希望每個類都專門化整個類。下面我的代碼的問題是,stringstream停止流了出來,當它擊中一個空間:如何將std :: string轉換爲構造函數中的幾種類型之一?

#include <iostream> 
#include <string> 
#include <sstream> 

using namespace std; 

template <typename Ty> 
struct Test 
{ 
    Ty value; 

    Test(string str) { 
     stringstream ss; 
     ss.str(str); 
     ss >> value; 
    } 
}; 


int main() 
{ 
    Test<int> t1{"42"}; 
    Test<double> t2{"3.14159"}; 
    Test<string> t3{"Hello world"}; 

    cout << t1.value << endl << t2.value << endl << t3.value << endl; 

    return 0; 
} 

上述代碼的輸出是:

42 
3.14159 
Hello 

,而不是「世界,你好」。有什麼辦法可以讓stringstream不會停留在空白區域,或者其他一些設備會像我需要的那樣進行任意轉換?

+1

我建議看看[Boost.Lexical_Cast](http://www.boost.org/doc/libs/1_61_0/doc/html/boost_lexical_cast.html) –

回答

1

這適用於我。廣義實施前只需要聲明一個特殊的實現:

#include <iostream> 
#include <string> 
#include <sstream> 

template<typename T> 
struct Test { 
    T value; 
    Test(std::string); 
}; 

template<> 
inline Test<std::string>::Test(std::string str) { 
    value = str; 
} 

template<typename T> 
inline Test<T>::Test(std::string str) { 
    std::stringstream ss; 
    ss.str(str); 
    ss >> value; 
} 

int main() { 
    Test<int> t1{"42"}; 
    Test<double> t2{"3.14159"}; 
    Test<std::string> t3{"Hello world"}; 

    std::cout 
     << t1.value << std::endl 
     << t2.value << std::endl 
     << t3.value << std::endl; 

    return 0; 
} 

下面是一個ideone工作示例。

+0

嘿,這個工程。我不知道你可以專門化構造函數,而不需要專門研究整個類。關鍵不在於定義類中的構造函數;一般情況和專業化都在外面。另一方面,由於在類之外進行專門研究,我必須將我的構造函數的兩個版本標記爲「inline」,以避免多重定義錯誤。 – Carlton

+0

如果它在標題中定義,那麼您需要這樣做。我會更新我的答案。也意識到一些編譯器在專門定義之前需要'template <>'(可能用C++ 14),所以更新也是如此 – Assimilater

+0

是的,GCC 4.9.3需要'template <>'。忘了提到這一點。 – Carlton

相關問題