Ich habe Schwierigkeiten zu verstehen, warum der folgende Code eine implizite Konvertierung nicht zulässig ist.Verwenden von benutzerdefinierten Konvertierungen mit impliziten Konvertierungen in Vergleichen
#include <string>
using namespace std;
struct HasConversionToString {
HasConversionToString(const string& s_) : s{s_} {}
string s;
operator const string&() const { return s; }
};
int main() {
string s{"a"};
HasConversionToString obj{"b"};
return s < obj;
}
Beiden Klirren und gcc keine gültigen Weg finden, die beiden Objekte mit Fehlern entlang der Linien zu vergleichen:
clang++ -std=c++14 -Wall -Wextra -pedantic conversion.cpp -o test
conversion.cpp:13:12: error: invalid operands to binary expression ('string' (aka 'basic_string<char>') and 'HasConversionToString')
return s < obj;
~^~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/stl_pair.h:220:5: note: candidate template ignored: could not match
'pair' against 'basic_string'
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/stl_iterator.h:298:5: note: candidate template ignored: could not match
'reverse_iterator' against 'basic_string'
operator<(const reverse_iterator<_Iterator>& __x,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/stl_iterator.h:348:5: note: candidate template ignored: could not match
'reverse_iterator' against 'basic_string'
operator<(const reverse_iterator<_IteratorL>& __x,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/stl_iterator.h:849:5: note: candidate template ignored: could not match
'__normal_iterator' against 'basic_string'
operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/stl_iterator.h:856:5: note: candidate template ignored: could not match
'__normal_iterator' against 'basic_string'
operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/stl_iterator.h:1089:5: note: candidate template ignored: could not match
'move_iterator' against 'basic_string'
operator<(const move_iterator<_IteratorL>& __x,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/stl_iterator.h:1095:5: note: candidate template ignored: could not match
'move_iterator' against 'basic_string'
operator<(const move_iterator<_Iterator>& __x,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/basic_string.h:4989:5: note: candidate template ignored: could not match
'basic_string<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2>' against 'HasConversionToString'
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/basic_string.h:5001:5: note: candidate template ignored: could not match
'const _CharT *' against 'HasConversionToString'
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.0/../../../../include/c++/5.3.0/bits/basic_string.h:5013:5: note: candidate template ignored: could not match
'const _CharT *' against 'string' (aka 'basic_string<char>')
operator<(const _CharT* __lhs,
^
1 error generated.
während des folgenden Code funktioniert gut, wenn ich warf das Objekt explizit ein Faden.
#include <string>
using namespace std;
struct HasConversionToString {
HasConversionToString(const string& s_) : s{s_} {}
string s;
operator const string&() const { return s; }
};
int main() {
string s{"a"};
HasConversionToString obj{"b"};
return s < static_cast<string>(obj);
}
auf der Grundlage der Regeln und on cppreference für implizite Abgüsse aufgeführten Beispiele, sehe ich keinen Grund, warum dies nicht funktionieren sollte. Ich nehme an, dass sowohl clang als auch gcc das gleiche nicht vermasselt haben, also stelle ich mir vor, dass ich ein konzeptionelles Missverständnis habe.
Ist dies ein Fall von SFINAE? – MtRoad
@MtRoad Hier gibt es keine Ersetzung. –
Gibt es irgendeinen vernünftigen Weg? Ich machte absichtlich die Konvertierung zurück, um die unglückliche unerwartete Zuteilung zu vermeiden. – David