operator TYPE()
{
return 값;
}
class Int32
{
int value;
public:
Int32() : value(0) {}
Int32(int n) : value(n) {} // 변환 생성자
operator int() const { return value; } // 상수 멤버 함수로 만들면 활용도 증가
};
int main()
{
int pn; // Primitive Type
Int32 un; // User Type
pn = un; // un.operator int() 호출
un = pn; // pn.operator Int32()는 int에 만들수 없어 아래 함수 찾음
// 1. un.operator=(pn) 대입 연산자
// 2. Int32(pn) 변환 생성자
}
class Int32
{
...
Int32(const Int32&) = delete; // 복사 생성자 삭제
}
int main()
{
Int32 n = 3; // Int32 n = Int32(3);
}
C++14까진 임시객체를 생성하여 복사 생성자나 move 생성자 호출
C++17부턴 임시객체를 생성하지 않고 인자가 한 개인 생성자 호출
class Int32
{
...
Int32& operator=(const Int32&) = delete; // 디폴트 대입 연산자 삭제
}
int main()
{
n = 3; // n = Int32(3); 컴파일 에러
}
컴파일러에서 최적화를 통해서 임시객체 생성이 제거되지만 문법적으론 디폴트 대입 연산자 필요
class Vector
{
public:
explicit Vector(int size) {}
};
void foo(Vector v) {} // Vector v = 3
int main()
{
Vector v1(3); // Direct Initialization
Vector v2 = 3; // Copy Initialization, 컴파일 에러
Vector v3{3}; // Direct Initialization C++11
Vector v4 = {3}; // Copy Initialization C++11, 컴파일 에러
v1 = 3; // 컴파일 에러
foo(3); // 컴파일 에러
}
class Machine
{
int data = 10;
bool state = true;
public:
explicit operator bool() { return state;}
};
int main()
{
Machine m;
bool b1 = m; // error
bool b2 = static_cast<bool>(m); // ok
m << 10; // error
if ( m )
{
}
}
// C++20
#include <type_traits>
template<class T>
class Number
{
T value;
public:
explicit(!std::is_integral_v<T>) Number(T v) : value(v) {}
};
int main()
{
Number n1 = 10; // ok
Number n2 = 3.4; // error
}
struct Alloc
{
std::size_t size;
Alloc(std::size_t sz) : size(sz) {}
template<class T>
operator T*() { return new T[size]; }
};
int main()
{
int* p1 = Alloc(10); // 임시객체.operator int*()
double* p2 = Alloc(10); // 변환 연산자가 템플릿이니 double도 가능
delete[] p1;
delete[] p2;
}