Re[5]: Возможна ли перегрузка оператора = в виде отдельной ф
От: Кодт Россия  
Дата: 14.08.09 09:49
Оценка:
Здравствуйте, navrocky, Вы писали:

N>Тоесть получается мне остается только писать функции?:

N>
N>B A_to_B(A);
N>A B_to_A(B);
N>


N>Через равно никак?


Напрямую — никак.
Кроме того, лексема "=" перегружена: это и оператор присваивания, и участник стейтмента инициализации. Оба действия близки и по виду, и по смыслу, но радикально отличаются с точки зрения компилятора.
Поэтому единственная дорога — это определение приведения типов: или со стороны "откуда" (operator куда() const), или со стороны "куда" (конструктор куда(откуда const&)).
Вариант с перегрузкой любого другого оператора (например, <<=) в роли присваивания не создаёт возможность инициализировать.

Однако, можно прибегнуть к посреднику — имитации static_cast'а.
// пусть у нас есть семейство перегруженных функций
A make_a(const B&);
A make_a(const C&);

// посредник - для засахаривания вызова функции в static_cast
struct to_a
{
    A m_a;
    to_a(const A& t) : m_a(t) {}
    template<class T> to_a(const T& t) : m_a(make_a(t)) {}
    operator A const&() const { return m_a; }
};

B b;
C c;

A a1 = (to_a) b; // здесь c-style cast, сводящийся к static_cast B --> to_a, а затем неявный static_cast to_a --> A
A a2 = (to_a) c;

// абсолютно то же самое
A a3 = static_cast<to_a>(b); // по-прежнему следом за явным B --> to_a идёт неявный to_a --> A

// без сахара и промежуточных объектов
A a4 = make_a(b);


Посредник ещё удобен тем, что он может совершать дополнительные действия: вести лог, выполнять валидацию, и т.д. и т.п.

Выше приведён минимальный каркас посредника, хотя, если попрыгать-поплясать, можно сделать универсальный всемогутер.
Скажем, вот так
template<class Traits>
struct convertor
{
    typedef typename Traits::result_type result_type;
    result_type m_t;
    
    template<class T> convertor(const T& t) : m_t(Traits::convert(t)) {}
    operator result_type const&() const { return m_t; }
};


struct convert_to_a
{
    typedef A result_type;
    
    static A const& convert(A const& t) { return t; }
        // мало ли, как мы захотим обрабатывать тождественное преобразование?
        // поэтому оно тоже отдаётся на откуп трейтсу
        
    template<class T> static A convert(T const& t) { return ::make_a(t); }
        // здесь используем внешние функции (перегруженные как угодно)
        // хотя можно и внутри класса определить всё необходимое
};

typedef convertor<convert_to_a> to_a;
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.