2013-08-02 74 views
3

我正在通過boost::variant,想知道如何才能使下面的工作?從istream中讀取boost :: variant類型

typedef boost::variant<int,std::string> myval; 
int main() 
{ 

std::vector<myval> vec; 

std::ifstream fin("temp.txt"); 

//How following can be achieved ? 
std::copy(std::istream_iterator<myval>(fin), //Can this be from std::cin too ? 
      std::istream_iterator<myval>(), 
      std::back_inserter(vec)); 
} 

對於類的數據成員,我們必須選擇重載>>操作,但如何與myval做到這一點?

回答

3

對於variant,您可以重載operator>>,就像其他任何類型一樣。但是由您來實現邏輯來決定從流中讀取什麼類型並存儲在variant中。這裏是你怎麼可能去做一個完整的例子:

#include "boost/variant.hpp" 
#include <iostream> 
#include <cctype> 
#include <vector> 
#include <string> 

typedef boost::variant<int, std::string> myval; 

namespace boost { // must be in boost namespace to be found by ADL 
std::istream& operator>>(std::istream& in, myval& v) 
{ 
    in >> std::ws;  // throw away leading whitespace 
    int c = in.peek(); 
    if (c == EOF) return in; // nothing to read, done 

    // read int if there's a minus or a digit 
    // TODO: handle the case where minus is not followed by a digit 
    // because that's supposed to be an error or read as a string 
    if (std::isdigit(static_cast<unsigned char>(c)) || c == '-') { 
     int i; 
     in >> i; 
     v = i; 
    } else { 
     std::string s; 
     in >> s; 
     v = s; 
    } 
    return in; 
} 
} // namespace boost 

// visitor to query the type of value 
struct visitor : boost::static_visitor<std::string> { 
    std::string operator()(const std::string&) const 
    { 
     return "string"; 
    } 
    std::string operator()(int) const 
    { 
     return "int"; 
    } 
}; 

int main() 
{ 
    std::vector<myval> vec; 
    std::copy(
     std::istream_iterator<myval>(std::cin), 
     std::istream_iterator<myval>(), 
     std::back_inserter(vec)); 

    std::cout << "Types read:\n"; 
    for (const auto& v : vec) { 
     std::string s = boost::apply_visitor(visitor(), v); 
     std::cout << s << '\n'; 
    } 
} 

例輸入:1 2 3 hello 4 world

輸出:

Types read: 
int 
int 
int 
string 
int 
string 
+0

關聯,得到你想說的話,這真的是很好的方法。但由於某種原因,我把所有的都當作'string'。我正在使用MingW 4.7.2 – P0W

+0

@ P0W你是指輸出中的所有字符串?即使你輸入了整數並且輸入了我發佈的確切代碼? – jrok

+0

@PW Nevermind,'if'語句中存在一個愚蠢的錯誤,修正了。 – jrok

0

myval只是一種類型。您根據類型重載運算符。

std::istream &operator >>(std::istream &stream, myval &val) 
{ 
    //Put stuff here. 
} 

至於什麼放在那裏,這是完全高達你和你所期望或要求那裏是流中的內容。

+3

將這個運算符參與名稱查找?恐怕你必須把它放在'boost'或'std'命名空間中。 –

+0

@NicolBolas'std :: istream&operator >>(std :: istream&stream,myval&val){return stream >> val; }'不能編譯。 但是'myval x; std :: cin >> x;'編譯(重載後),但可執行文件崩潰 – P0W

+0

@NicolBolas,謝謝,現在我通過與jrok的示例 – P0W