Der Grund dafür ist, dass ein Standard-Algorithmus genannt std::distance existiert, die von ADL (Argumente abhängige Lookup) gefunden wird: Obwohl Ihr Anruf mit dem std
Namespace nicht qualifiziert ist, die Art Ihrer Argumente a
und b
(dh std::string
) Leben im selben Namespace wie die std::distance
-Funktion (dh std
), und daher wird auch std::distance()
für die Überlastungsauflösung berücksichtigt.
Wenn Sie wirklich Ihre Funktion distance()
aufrufen möchten (ich würde vorschlagen, Sie nicht), können Sie entweder in einem Namespace von Ihnen eingeben, und dann den Funktionsnamen vollständig qualifizieren, wenn Sie es aufrufen, oder lassen Sie es der globale Namespace und rufen sie es auf diese Weise:
::distance(a, b);
// ^^
Beachten sie jedoch, dass ADL allein könnte nicht Ursache Ihr Programm kompiliert wird scheitern, wenn Ihre Implementierung der Standardbibliothek eine SFINAE freundliche Version iterator_traits
bietet (mehr Details in this Q&A on StackOverflow - mit freundlicher Genehmigung von MooingDuck).
Mit einer SFINAE freundlichen Umsetzung von iterator_traits
, Compiler, dass die std::distance()
Funktion Vorlage erkennen soll (weil es eine Vorlage) nicht instanziiert, wenn Argumente von std::string
Art gegeben werden kann, aufgrund seines Rückgabetypen:
template< class InputIt >
typename std::iterator_traits<InputIt>::difference_type
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Trying to instantiate this with InputIt = std::string
// may result in a soft error during type deduction if
// your implementation is SFINAE-friendly, and in a hard
// error otherwise.
distance(InputIt first, InputIt last);
In diesem Fall würde der Compiler diese Vorlage einfach für die Überladungsauflösung verwerfen und Ihre distance()
Funktion auswählen.
Wenn jedoch Ihre Implementierung der Standardbibliothek keine SFINAE-freundliche Version von iterator_traits
bereitstellt, kann in einem Kontext, der nicht für SFINAE geeignet ist, ein Substitutionsfehler auftreten, was zu einem (harten) Kompilierungsfehler führt.
Diese live example zeigt Ihr ursprüngliches Programm kompilierend mit GCC 4.8.0, das mit einer Version von libstdC++ geliefert wird, die eine SFINAE-freundliche iterator_traits
implementiert.
Ich wusste sofort, was das Problem war. Wenn ich nur drei Stunden früher hier wäre. Lol – 0x499602D2