2010-09-14 11 views
7

Uczę się C++. Regularnie pojawiają się błędy, które wyglądają jak toJak odczytywać błędy w C++ związane z szablonami

/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/basic_string.h:1458: instantiated from 'static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct_aux(_InIterator, _InIterator, const _Alloc&, std::__false_type) [with _InIterator = std::istream_iterator, std::allocator >, char, std::char_traits, int>, _CharT = char, _Traits = std::char_traits, _Alloc = std::allocator]'

Jak mogę zrozumieć to tak, że mogę mieć przynajmniej jakieś miejsce do poszukiwania rozwiązania?

W przypadku jesteś zainteresowany, oryginalny kod jest:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <iterator> 

using namespace std; 

int main(int argc, char **argv) { 
    string fileName = "example.txt"; 
    ifstream ifile(fileName.c_str()); 

    istream_iterator<string> begin(ifile); 
    istream_iterator<string> end; 

    string s(begin,end); 
    cout << s; 
} 

Odpowiedz

6

To nie jest cały błąd, tylko opis w jednej instancji.

Zasadniczo dbasz o:

1), która linia w kodzie wywołał błąd (string s(begin,end);)

2) Jaki błąd nie spowodować (np cannot convert 'const std::basic_string<char, std::char_traits<char>, std::allocator<char> >' to 'char' in assignment) i gdzie

3) możesz porównać to, co kompilator mówi, że parametry szablonu są i jakie są twoje założenia.

To prawdopodobnie wymaga doświadczenia, aby nie bać się błędów i na pewno pomaga dobrze poznać bibliotekę.

W tym przypadku przyczyną jest to, że konstruktor ciągu oczekuje szeregu znaków, ale przechodzisz zakres ciągów znaków.

5

Zastosowanie STLFilt.

+0

Lol, to jest niesamowite. Czy to pomaga w przyspieszeniu? Tam naprawdę było potrzebne. –

+0

@TED: Tak: http://www.bdsoft.com/dist/vcmeta-demo.txt (jest lepiej, ale nie rewelacyjnie) –

3

Comeau ma znacznie bardziej przyjazny kompilator, to sprawdzić na stronie: http://www.comeaucomputing.com/tryitout/

na przykład, jest to błąd:

Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 
Copyright 1988-2008 Comeau Computing. All rights reserved. 
MODE:strict errors C++ C++0x_extensions 

"string", line 1175: error: no suitable conversion function from 
      "const std::string" to "char" exists 
     push_back(*__first); 
       ^
      detected during instantiation of "std::basic_string<_CharT, _Traits, 
        _Alloc> &std::basic_string<_CharT, _Traits, 
        _Alloc>::append(_InputIter, _InputIter, 
        std::input_iterator_tag) [with _CharT=char, 
        _Traits=std::char_traits<char>, 
        _Alloc=std::allocator<char>, 
        _InputIter=std::istream_iterator<std::string, char, 
        std::char_traits<char>, ptrdiff_t>]" at line 624 

1 error detected in the compilation of "ComeauTest.c". 

który prowadzi mnie założenie, że konstruktor oczekuje char iterarator zamiast iterator przez ciągi znaków (jak w wielu strunach):

istream_iterator<char> begin(ifile); 
istream_iterator<char> end; 
+0

Moim zdaniem część push_back w twoim komunikacie o błędzie przeszywa mój umysł ... W pierwszym przypadku nie ma to nic wspólnego z problemem. Pierwsze dwie linie są jednak lepsze, muszę przyznać :) – rubenvb

+0

@ruben czasem trzeba iść z intuicją – Anycorn

2

Rzeczywiście pominięto kluczowe części komunikatu o błędzie. Otrzymujesz dwa zduplikowane błędy w g ++ 4.2. Kluczowymi częściami są: /path/basic_string.tcc:103: error: cannot convert 'const std::basic_string<char, std::char_traits<char>, std::allocator<char> >' to 'char' in assignment i str_iter_test.C:15: instantiated from here.

Pierwsza część oznacza, że ​​nie mogła dokonać konwersji z ciągu znaków na znak, a druga część mówi, w którym wierszu wystąpił błąd, w tym przypadku string s(begin,end);.

W tym przypadku Twoje iteratory powinny iteracyjne nad char nie string:

istream_iterator<char> begin(ifile); 
istream_iterator<char> end; 
1

Konkretny komunikat pokażesz powinien być tylko częścią błędu wydanego przez g ++. Pełne błąd powinien wyglądać bliżej poniżej (mam skróceniu ścieżki, i wyjście to od 4.1.2):

basic_string.tcc: In static member function 'static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::input_iterator_tag) [with _InIterator = std::istream_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char>, int>, _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]': 
basic_string.h:1449: instantiated from 'static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct_aux(_InIterator, _InIterator, const _Alloc&, __false_type) [with _InIterator = std::istream_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char>, int>, _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
basic_string.h:1464: instantiated from 'static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&) [with _InIterator = std::istream_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char>, int>, _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
basic_string.tcc:241: instantiated from 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(_InputIterator, _InputIterator, const _Alloc&) [with _InputIterator = std::istream_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char>, int>, _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
t.cpp:16: instantiated from here 
Line 101: error: cannot convert 'const std::basic_string<char, std::char_traits<char>, std::allocator<char> >' to 'char' in assignment 
compilation terminated due to -Wfatal-errors. 

To nie jest o wiele bardziej przyjazny, to jest? :-) Przydatne linie w błędzie to linie na końcu, a nie linie na początku.Komunikat o błędzie jest wydawane w odwrotnej kolejności: pierwszy błąd jest faktycznym błędem, następnie kolejne linie dostarczają ścieżek menu za pośrednictwem źródła pokazującego, w jaki sposób kompilator się tam dostał. Ostatnia linia pokazuje gdzie w źródle Wystąpił błąd:

t.cpp:16: instantiated from here 
Line 101: error: cannot convert ' 
    const std::basic_string<char, std::char_traits<char>, std::allocator<char> >' to 
    'char' in assignment 

w moim przykładzie pliku t.cpp:16 jest następujący wiersz:

string s(begin,end); 

Jeśli skomentuj tę linię (a linia po nim, że używa s), przekonasz się, że twoje źródło kompiluje się bezbłędnie.

W tym miejscu powinno być całkiem jasne, że używasz konstruktora std::string niepoprawnie, co oznacza, że ​​przekazujesz mu niewłaściwe typy argumentów. Dajesz mu coś, co ma std::string (to jest std::basic_string<char>) i oczekuje czegoś, co ma char.

Jeśli skonsultować się z dokumentacją std::string, przekonasz się, że to ma konstruktora, który wygląda tak:

template <typename InputIterator> 
string(InputIterator first, InputIterator last); 

te iteratory wejściowe pozwalają tworzyć ciąg z zakresu znaków. Przekazujesz jednak zakres std::string s do konstruktora. Jeśli zmienisz swoje istream_iterator<string> s na istream_iterator<char>, które powinno naprawić błąd.

Powiązane problemy