2014-08-27 1 views
2

Я проверил вопросы по StackOverflow (особенно casting operator - const vs non-const) и user-defined conversion - cppreference.com, но я не нашел полезных примеров для неконстантной версии.Когда реализовать оператор неконсольного литья

В каких случаях оператор бесконтактного литья имеет смысл?


фон (редактировать): Вопрос пробуждать от простой реализации в Факультативным класса шаблона для плоских макетов памяти. Здесь я хотел неявное приведение к содержащемуся типу, и мой первый подход, как это (без const):

template <typename T> 
    class Optional 
    { 
    public: 
     operator T() { return value; } 
     // ... 
    private: 
     T value; 
     // ... 
    }; 

После того, как компилятор напомнил мне об этом, мне было интересно, если это (при возвращении RValue) было бы просто неправильно в любом случае.

ответ

2

Очевидным ответом является преобразование к Lvalue:

class MyInt 
{ 
    int m; 

public: 
    operator int&() { return m; } 
    operator int() const { return m; } 
}; 

Я не могу думать ни о каком конкретном примере за что. Я предполагаю, что это может иметь смысл в некоторых языках, специфичных для домена, где вся система типа C++ является всего лишь средством доставки некоторого синтаксиса.

3

Одна жизнеспособная причина заключается в том, что оператор литья не возвращает значение, а ссылку какого-то рода; вы не хотите, чтобы приведение нарушало любые const -ness объекта.

class Type { 
    HANDLE h; 
public: 
    operator HANDLE const&() const { 
    return h; 
    } 
    operator HANDLE&() { // possibly want the non-const as well 
    return h; 
    } 
}; 

По моему опыту, я думаю, что я вспоминаю один экземпляр этого, и это должно было сделать нас из-за щепотки.

+0

Что защемляет? И еще более интересно: хорошо ли это работает? – Wolf

+0

@ Вольф, в основном парень написал на заказ код и покинул компанию. Затем код должен был быть развернут несколькими месяцами позже, не работал, был заполнен утечками памяти и т. Д. - это был самый короткий способ заставить его работать и с необходимой нам совместимостью практически не было времени. Это сработало, это было некрасиво. – Niall

1

Вы можете иметь дело, где вы должны изменить внутреннее состояние вашего объекта, когда оператор литья называется:

class CounterInt { 
private: 
    int m_value; 
    int m_state; 
public: 
    CounterInt(int val) : m_value(val), m_state(0) {} 
    operator int() { 
    ++m_state; 
    return m_value; 
    } 
    int getState() {return m_state;} 
}; 

Это не возможно, если ваш оператор литья Уст. Wether или нет, это хорошая идея (или если вы должны изменить состояние), это еще один вопрос.

+0

Хорошо, это я, вероятно, решаю, сделав m_state' mutable; Думаю, это цель изменчивого. – Wolf

+0

@ Вольф в большинстве случаев согласен. Это зависит от того, как вы собираетесь использовать его в конце. Этот код, например, изменяет открытый интерфейс ('CounterInt :: getState()') объекта, поэтому он не является ни логическим, ни побитовым. Но, с другой стороны, это полностью сфабриковано и, скорее всего, не появится ни в одном реальном коде. – MatthiasB

+1

Теперь я обнаруживаю, что ваш ответ ближе к моему вопросу, чем я думал в первую очередь. Возможно, более эффективная функция-член будет более приемлемой, например, что-то вроде генератора случайных чисел. – Wolf

Смежные вопросы