나는 std::cout << x
을 쓰려고 할 때 발생하는 컴파일 오류에 다소 짜증이 나서 왼쪽 시프트 연산자는 x
에 대해 정의되지 않았습니다. x를 (으)로 변환 할 수 없으며 x를 그 것으로 변환 할 수 없습니다 ... 쓸모없는 오류 메시지의 여러 화면.연산자 대체 << 모든 유형의 경우
해당 연산자가 아직 정의되지 않은 모든 유형에 대해 operator<<(std::ostream&, const T&)
을 전문화하고 싶습니다. 내부에 정적 어설 션을 넣고 컴파일 오류 메시지를 훨씬 더 선명하게 만들 수 있습니다.
첫 번째 시도는 다음과 같습니다.
template<typename T, typename = void>
struct Has : public std::false_type {};
template<typename T>
struct Has<T, decltype(void(
std::declval<std::ostream&>() << std::declval<T>()
))> : public std::true_type {};
template<typename T>
auto operator<<(std::ostream& out, const T&)
-> typename std::enable_if<
!Has<T>::value,
std::ostream&>::type
{
return out << "my operator";
}
최대 템플릿 깊이를 초과하기 때문에 컴파일에 실패합니다. 실제로 operator<<
은 Has
전문화를 호출하여 operator<<
으로 전화를 걸고 여기서 내 과부하가 다시 검사되는 등 계속 반복됩니다.
가장 간단한 버전도 작동하지 않습니다. std::ostream& << const char*
에 대한 모호한 오버로드입니다. 예상 했어.
template<typename T>
std::ostream& operator<<(std::ostream& out, const T&)
{
return out << "my operator";
}
어떻게해야합니까? 또는 일반적으로 모든 인수 유형에 대해 함수를 정의 할 수 있지만 함수에 이미 전달 될 수있는 인수 유형에 대해서는 어떻게 정의 할 수 있습니까?
[이발사의 역설] (https://en.wikipedia.org/wiki/Barber_paradox) –
@IgorTandetnik 정확하지는 않습니다. 이발사의 관점에서 볼 때 '이브닝 이발사는 아직 면도하지 않은 모든 사람들을 면도 할 것'이라고 생각합니다. _elsewhere_ 함수에서 허용하지 않는 모든 유형에 대해 함수를 정의하려고합니다. 나는 여기서 역설을 발견하지 못한다. –
잘 구성된 프로그램에서 그러한 연산자를 사용하는 것은 아마도 불가능할 것입니다. 연산자의 정의는 인스턴스화 시점에서 어떤 특수화가 표시되는지에 따라 달라집니다. 번역 단위가 다르거 나 번역 단위가 다를 수도 있습니다 (** ** [포인트]/8 **), 이는 ODR 위반이 될 수 있으며, 프로그램을 부적절하게 만들지 만 진단은 필요하지 않습니다. –