저는 프로젝트에서 템플릿 변형 명시 연산자를 사용하여 변형 된 유사 유형의 명시적인 변환을 구현했습니다. 내 문제를 재현 최소한의 예는 다음 (14 ++ C 모드)과 같은 : 내가 직면명시 적 변환 연산자 템플릿의 우선 순위와 모호성
#include <iostream>
#include <stdexcept>
#include <cmath>
using namespace std;
class A
{
public:
template<typename T> explicit operator T() const // 1
{
cout << "operator T" << endl;
return T();
}
template<typename T> explicit operator const T&() const // 2
{
cout << "operator const T&" << endl;
throw runtime_error("operator const T&");
}
template<typename T> explicit operator T&() // 3
{
cout << "operator T&" << endl;
throw runtime_error("operator T&");
}
};
int main(int, char**)
{
try
{
const A& a = A();
cout << abs(static_cast<double>(a) - 3.14) << endl;
}
catch (const runtime_error&)
{
}
return 0;
}
문제는 static_cast 변환을 위해 선택한 연산자입니다. GCC의 경우 예상되는 (1) 경우입니다. 출력은 다음과 같습니다
operator T
3.14
그러나 연타는 다음과 같은 출력이 컴파일을 거부 :
main.cpp:37:20: error: ambiguous conversion for static_cast from 'const A' to 'double'
cout << std::abs(static_cast<double>(a) - 3.14) << endl;
^~~~~~~~~~~~~~~~~~~~~~
main.cpp:10:32: note: candidate function [with T = double]
template<typename T> explicit operator T() const
^
main.cpp:16:32: note: candidate function [with T = double]
template<typename T> explicit operator const T&() const
^
1 error generated.
연타가 변환이 생각하는 이유 (2), 그것은 분명히 변환 순서에 추가 생성자 호출을 필요로 할 때, 동안 (1) 않을까요? 그리고 그것이 옳은가? (그리고 GCC는 틀린가?) 그렇게하고 있는가?
하지만 왜이 작업을 수행할까요? ''연산자 T()''와''연산자 const T &''둘 다 갖는 점은 무엇입니까? –
@ArneVogel 실제 코드에서이 코드의 의도는 대체 변환 시퀀스를 제공하는 것입니다. 예를 들어, 변형이 'long double'을 보유하면 '연산자 T()'는 'int'로 변환하는 데 도움이됩니다. 하지만 실제로'static_cast'가 실제로 수행하는 것들을 오해했기 때문에이 값으로의 변환은 실제로 중복됩니다. – aclex