При каких обстоятельствах будет вызываться оператор преобразования типа для себя?

Рассмотрим тип bar, который имеет определенные пользователем операторы преобразования для ссылок типа bar:

struct bar
{
  operator bar & ();
  operator const bar & () const;
};

Когда будут применены эти преобразования? Более того, что означает, что эти операторы были deleted? Есть ли интересное использование любой функции?

В следующей программе не применяется преобразование:

#include <iostream>

struct bar
{
  operator bar & ()
  {
    std::cout << "operator bar &()" << std::endl;
    return *this;
  }

  operator const bar & () const
  {
    std::cout << "operator const bar &() const" << std::endl;
    return *this;
  }
};

void foo(bar x)
{
}

int main()
{
  bar x;

  bar y = x;         // copy, no conversion

  y = x;             // assignment, no conversion

  foo(x);            // copy, no conversion

  y = (bar&)x;       // no output

  y = (const bar&)x; // no output

  return 0;
}

Ответ 1

С++ 11 §12.3.2

Функция преобразования никогда не используется для преобразования (возможно, cv-квалифицированного) объекта к (возможно, cv-квалифицированному) одному типу объекта (или ссылке на него) к базовому классу (возможно, cv-qualit) этого тип (или ссылку на него) или (возможно, cv-qualified) void

Ответ 2

Функция, позволяющая вам определить функцию преобразования от типа к себе, но что функция преобразования никогда не используется, может быть полезной функцией в программировании шаблонов, где два параметра типа могут ссылаться или не ссылаться на один и тот же тип, в зависимости от экземпляра. Некоторое кодовое слово основывается на этой функции. Это экономит необходимость предоставления специализаций для случаев, когда два или более параметров типа в конечном итоге ссылаются на один и тот же тип.

Ответ 3

Я не вижу причин, почему это когда-либо будет вызвано. Функции преобразования вызывают преобразование. Если у вас уже есть правильный тип, нет никаких оснований для добавления операции преобразования перед копией.

Ответ 4

Только для записи. Мне удалось создать такую ​​структуру в более крупном программном проекте, слепо доверяя предупреждению компилятора и удалив "никогда не использованный метод". Ну, я думаю, я нашел сценарий, где он фактически называется. Компилятор, похоже, пропустил базовый класс.

#include <iostream>

struct D;
struct B
{
    virtual operator D& ()
    {
        throw "foo";
    }
};

struct D : public B
{
    virtual operator D& ()
    {
        std::cout << "bar" << std::endl;
        return *this;
    }
};

int main()
{
    B* b = new D();
    D& d = *b;

    return 0;
}