다음 코드는 MSVC 2017 년까지 거부 (그러나 GCC/연타에 의해 허용)된다과부하 해결 : 사용자 정의 변환보다 const/ref를 조정하고 있습니까?
class BA
{
private:
operator int() const;
};
template <typename A, typename B>
class Builder {};
template <typename C>
struct Concatenable;
template <int N> struct Concatenable<char[N]>
{
using type = char[N];
};
template <int N> struct Concatenable<const char [N]>
{
using type = const char[N];
};
template <> struct Concatenable<BA>
{
using type = char *;
};
template<typename A, typename B>
Builder<typename Concatenable<A>::type, typename Concatenable<B>::type>
operator+(const A &, const B &)
{
return {};
}
int main()
{
BA ba;
char array[] = {'a', 'b'};
ba + array;
}
오류 : MSVC가 const char (&)[2]
에 BA
보다 더 나은 char[2]
을 조정하는 것을 고려하고있다처럼 보이는
example.cpp
40 : <source>(40): error C2666: 'operator +': 2 overloads have similar conversions
31 : <source>(31): note: could be 'Builder<char *,char [2]> operator +<BA,char[2]>(const A &,const B (&))'
with
[
A=BA,
B=char [2]
]
40 : <source>(40): note: or 'built-in C++ operator+(__int64, char [2])'
40 : <source>(40): note: while trying to match the argument list '(BA, char [2])'
40 : <source>(40): note: note: qualification adjustment (const/volatile) may be causing the ambiguity
int
로 변환합니다. 표준을 읽으면서 이것이 사실이 아니어야합니다.
[over.ics.rank]는 표준 변환 시퀀스가 항상 사용자 정의 변환 시퀀스보다 우수한 변환이라고 말합니다. 지금 : 템플릿에서 인스턴스화
operator+
두 표준 변환 시퀀스- 사용 내장 한 사용자 정의 전환 서열 및 표준 변환 시퀀스 (
ptrdiff_t, char *
이상)
따라서 [over.match.best]의 규칙에 따르면, 내 operator+
은 항상 다른 것보다 나쁘지 않으며, 어떤 주장을하는 것이 좋습니다. 따라서 선호해야합니다. BA
에서 operator int
제거 또는 유사 const char[]
상기 배열의 변화, 또는 비 CONST 걸릴 operator+
번째 매개 변수를 변경하는 것은 B&
MSVC 행복하게
참고있다.
내가 무엇을보고 있지 않습니까?
다르게 마킹'운영자 int' (암시 적 사용자 정의 변환 연산자도 허용하는 이유?). 이것은 VC++의 버그 인 것 같습니다. 또한 참조를 바인딩으로 변환하는 것으로 간주됩니까? – VTT
적어도 내 독서에서 "신원 전환"으로 간주됩니다 ... http://eel.is/c++draft/over.ics.ref#1 – peppe