2012-03-15 51 views
2
int main() { 
    std::deque<std::string> mydeque; 
    std::back_insert_iterator<decltype(mydeque)> myback_insert_iterator(mydeque); 
    std::ifstream myifstream("test.txt"); 
    while(std::getline(myifstream, *myback_insert_iterator)) { 
    } 
} 

我只是想將一行文本文件讀入一個字符串容器。 這會產生編譯器錯誤:std :: getline不接受std :: back_insert_iterator

C2784: could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::ifstream'

怎麼了?

+0

你應該更喜歡'std :: back_inserter'來顯式聲明'back_insert_iterator '。 – pmr 2012-03-15 11:25:04

+0

注意,而不是在迭代器的聲明中使用'decltype',你可以用'的std :: back_inserter(mydeque)' - 這是一個函數模板,並推斷出類型爲您服務。你可以直接將它傳遞給你的函數,或者用'auto'聲明變量,使你的代碼更具可讀性。 – 2012-03-15 11:27:13

回答

5

嘗試:

int main() 
{ 
    std::deque<std::string> mydeque; 
    std::ifstream myifstream("test.txt"); 

    std::string line; 
    while(std::getline(myifstream, line) 
    { 
     mydeque.push_back(line); 
    } 
} 

如果是每行一個字就可以簡化爲:

int main() 
{ 
    std::deque<std::string> mydeque; 
    std::ifstream myifstream("test.txt"); 

    // Note: istream_iterator<T> uses std::istream& operator>>(std::istream&, T&) to 
    //  read data from the stream. If `T` is a std::string this means it will 
    //  read a single space separated word. 

    std::copy(std::istream_iterator<std::string>(myifstream), 
       std::istream_iterator<std::string>(), 
       std::back_inserter(mydeque) 
      ); 
} 

如果每行包含多個單詞和要使用背面插入,那麼你需要定義一個用於讀取可用於迭代器的對象中的整行的類:

struct Line 
{ 
    std::string data; 
    operator std::string const&() const {return data;} 

    friend std::istream& operator>>(std::istream& s, Line& dst) 
    { 
     return std::getline(s, dst.data); 
    } 
}; 

int main() 
{ 
    std::deque<std::string> mydeque; 
    std::ifstream myifstream("test.txt"); 

    std::copy(std::istream_iterator<Line>(myifstream), 
       std::istream_iterator<Line>(), 
       std::back_inserter(mydeque) 
      ); 
} 

或者我們可以只使用構造器:

int main() 
{ 
    std::ifstream myifstream("test.txt"); 
    std::deque<std::string> mydeque(std::istream_iterator<Line>(myifstream), 
            (std::istream_iterator<Line>())); 
    // Note: Extra brace required around second iterator here 
    //  This is to avoid the problem with the `Most Vexing Parse` 
    //  Which would otherwise make this a function declaration 

} 
+0

這可能會奏效。任何想法,爲什麼解除引用的insert_iterator行爲不同於可分配的字符串對象?因爲* myback_insert_iterator =「abc」;實際上工作正常。 – Simon1X 2012-03-15 11:37:54

+1

@ Simon1X:A [背面插入迭代](http://www.sgi.com/tech/stl/back_insert_iterator.html)是一個[輸出迭代](http://www.sgi.com/tech/stl/ OutputIterator.html)。從技術角度講,每次使用賦值運算符後,必須使用++運算符(請參見Output Iterator頁面中的註釋3)。分配後未遞增是未定義的行爲。它歸結到輸出迭代器沒有值類型因而操作*不返回引用的std :: string(實際類型爲未定義)。迭代器根據與操作員相關的預期輸出來定義。 – 2012-03-15 11:58:19

+0

@ simon1X C++是一種靜態類型語言。編譯器不知道行爲,知道語言結構和類型,迭代器不是字符串。 'getline'採用字符串作爲參數,而你需要可以被應用到迭代器(或許多其他類型的)操作的子集,編譯器會拒絕它的理由是,無論是*叫聲多麼響亮*不是*鴨子* – 2012-03-15 12:19:08

2

getline需要一個字符串,而不是輸出迭代器。你可以用myifstream爲輸入迭代器,並使用std::copy。像這樣:

#include <deque> 
#include <fstream> 
#include <algorithm> 
#include <iterator> 

int main() { 
    std::deque<std::string> mydeque; 
    std::back_insert_iterator<decltype(mydeque)> myback_insert_iterator(mydeque); 
    std::ifstream myifstream("test.txt"); 
    std::istream_iterator<std::string> i_it(myifstream), eos; 
    std::copy(i_it, eos, myback_insert_iterator); 
} 
+1

,你可以在編寫短:性病:: deque的 mydeque(的std :: istream_iterator (myifstream),(的std :: istream_iterator ()));但是,停止使用空格而不是換行符。 – Simon1X 2012-03-15 11:32:17

相關問題