2014-03-28 51 views
1

我想有兩個模板結構可以將任何Variant類型轉換爲std::strings;如何使用模板類型的向量?

雖然第一個編譯,第二個不會編譯,在vector<Variant>::iterator statement。編譯器說:

error: expected ';' after expression

vector<Variant>::iterator i = data.begin();

任何想法,我究竟做錯了什麼?有沒有更好的辦法來解決我在這裏要做的事情?

template <typename Variant> 
struct to_string 
{ 
private: 
    Variant data; 

public: 
    to_string(Variant &d) : data(d) {} 
    operator std::string() const 
    { 
     try 
     { 
      return boost::lexical_cast<std::string>(data); 
     } 
     catch (const boost::bad_lexical_cast &) 
     { 
      return std::string(); 
     } 
    } 

}; 

template <typename Variant> 
struct to_string_vector 
{ 
private: 
    vector<Variant> data; 
public: 
    to_string_vector(vector<Variant> &d) : data(d) {} 
    operator vector<std::string>() const 
    { 
     vector<string> ret; 
     vector<Variant>::iterator i = data.begin(); 
     to_string t_s<Variant> s = to_string<Variant>(*i); 
     ret.push_back((string)s); 
     return ret; 
    } 
}; 

回答

3

訪問subclassess或模板類型的範圍內定義的typedef何時需要幫助確定他們的類型,您需要

typename vector<Variant>::iterator 

編譯器就會犯糊塗。

編輯:(我的完整程序,修復了一些const ....因爲我現在沒有提升功能,所以增加了代碼來實例化模板)。

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

template <typename Variant> 
struct to_string 
{ 
private: 
    Variant data; 

public: 
    to_string(const Variant &d) : data(d) {} 
    operator std::string() const 
    { 
     //try 
     //{ 
      //return boost::lexical_cast<std::string>(data); 
     //} 
     //catch (const boost::bad_lexical_cast &) 
     //{ 
      return std::string(); 
     //} 
    } 

}; 

template <typename Variant> 
struct to_string_vector 
{ 
private: 
    vector<Variant> data; 
public: 
    to_string_vector(const vector<Variant> &d) : data(d) {} 
    operator vector<std::string>() const 
    { 
     vector<string> ret; 
     typename vector<Variant>::const_iterator i = data.begin(); 
     to_string<Variant> s = to_string<Variant>(*i); 
     ret.push_back((string)s); 
     return ret; 
    } 
}; 

int main(int argc,char **argv) { 

to_string<int> a(10); 

string sa=(string)a; 
vector<int> v; 
to_string_vector<int> b(v); 
vector<string> sb=(vector<string>)b; 
} 
+1

擴大這個;如果沒有'typename',編譯器會認爲'vector :: iterator'是一個變量名,因此是錯誤信息。畢竟你可以用'vector'的專門化來調用這個模板,在這裏你有一個名爲'iterator'的變量。這些規則的設計使編譯器可以進行一些檢查,甚至可以對模板進行部分編譯,而無需知道將使用哪種類型進行實例化。 –

+0

非常感謝您的答覆和解決! :-)如果你有一個更優雅或通用的方法來做同樣的事情的想法,請張貼:) – user3211860

0

雖然第一個編譯

我不這麼認爲。只要你的其他代碼使用它,那麼模板生成的代碼就會被編譯。

在這兩個結構中,您都是從const聲明的函數中訪問非const變量成員。你可以從你的函數中刪除const關鍵字,或者你需要將mutable關鍵字添加到你的變量中。

+1

只要看看「第一個」孤立 - 而構造沒有明顯的理由採取或存儲''Variant'由非''const'引用,如果調用上下文提供左值,則這樣做不是非法的。關於*「你正在從一個const聲明的函數中訪問非const變量成員」* - 在'operator std :: string()const'中是這樣,但在const中允許non-mutating access ala'lexical_cast <>' '功能。 –

相關問題