Возьмём простенький пример:
enum colors {red, green, blue};
struct proxy
{
operator colors () const
{
return red;
}
};
proxy f()
{
return proxy();
}
int main()
{
colors c = f(); // хорошо
int i = f(); // спорно, но компилируется
std::cout << f(); // спорно, но компилируется
unsigned u = f() + 1; // совсем спорно, но компилируется
if (f()) // совсем спорно, но компилируется
std::cout << "if\n";
}
Теперь немного допилим напильником:
struct proxy
{
operator colors () const
{
return red;
}
private: template<typename T> operator T () const;
};
int main()
{
colors c = f(); // хорошо
int i = f(); // не компилируется
std::cout << f(); // не компилируется
unsigned u = f() + 1; // не компилируется
if (f()) // не компилируется
std::cout << "if\n";
}
Получается что-то типа explicit conversion operator. Автоматически приводится только, если тип полность совпадает, в противном случае надо писать явный каст:
int main()
{
std::cout << (colors)f(); // ок
}
Таким же образом можно определить несколько типов, для которых должен быть неявное приведение:
class proxy
{
public: operator char const* () const
{
return "hello from proxy";
}
public: operator wchar_t const* () const
{
return L"hello from proxy";
}
private: template<typename T> operator T () const;
};
красота...
Комментариев нет:
Отправить комментарий