При каких обстоятельствах будет вызываться оператор преобразования типа для себя?
Рассмотрим тип 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;
}