2017-01-04 4 views
1
#include <iostream> 
#include <string> 

int main() { 
    using std::string; 
    using std::distance; 
    using std::cout; 
    using std::endl; 

    string s("abc"); 
    string::const_iterator b = s.begin(); 
    string::const_iterator e = s.end(); // success 
    cout << distance(b, e) << endl; 
    cout << distance(b, static_cast<string::const_iterator>(s.end())) << endl; 
    cout << distance(b, s.end()) << endl; // error 
    return 0; 
} 

Ende der Schnur s.end()implicitly converted zu std::string::const_iterator als e sein kann, aber wenn es als Funktionsparameter übergeben wird, hat es explizit gegossen werden; Andernfalls wird ein Fehler in der Kompilierzeit ausgelöst. Warum das?implizite Konvertierung nicht in Funktionsparameter

FYI, s.begin() und s.end() scheinen beide std::string::iterator zurückzukehren.

Ein Ausdruck e gesagt wird T2 implizit konvertierbar sein, wenn und nur wenn T2 aus e kopieren initialisiert werden, dass die Erklärung ist T2 t = e; wohlgeformt (kompiliert werden kann), für einige t temporäre erfunden .

+0

Danke euch beiden. Gültige Antworten Mein Fehler, keine Nicht-Template-Methoden auszuprobieren. –

Antwort

1

Die Funktion hat ein Template-Parameter

template <class InputIterator> 
typename iterator_traits<InputIterator>::difference_type 
distance(InputIterator first, InputIterator last); 

So kann es nicht den Typ des Template-Parameter ableiten, weil entweder Iterator const oder nicht-const kann für jeden Funktionsparameter verwendet werden.

könnten Sie schreiben, ohne die folgende Art und Weise zu Gießen

std::distance<std::string::const_iterator>(b, s.end()) 

explizit das Template-Argument angeben.

Ein anderes Beispiel. Dieser Code-Schnipsel wird auch nicht

long x = 0; 
int y = 0; 
std::min(x, y); 

jedoch kompilieren, wenn Sie

schreibt
long x = 0; 
int y = 0; 
std::min<long>(x, y); 

dann der Code kompiliert wird.

1

Template-Funktionsargumente werden nicht konvertiert. Die beiden Argumente zu std::distance müssen vom selben Typ sein.