понедельник, 26 мая 2008 г.

C++ интересный трюк с приведением типов

Нагло сперто с RSDN.

Возьмём простенький пример:

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;

};



красота...

Комментариев нет: