Возьмут следующий код:Передвижение оператора присваивания авто сгенерированного (VS ошибки?)
class Foo
{
Foo const& operator =(Foo const& rhs); // disallow
};
struct Bar
{
public:
Foo foo;
template <class T>
T const& operator =(T const& rhs) { return rhs; }
};
struct Baz : public Bar {
using Bar::operator =;
};
int main()
{
Baz b1, b2;
b1 = b2;
}
Это не может компилироваться, так как оператор присваивания автоматически сгенерированными для бара :: оператора = будет использоваться, который пытается использовать Foo :: operator =, который является приватным. Хорошо. Таким образом, я добавил в дополнительный элемент к бару:
Bar const& operator =(Bar const& b) { return Bar::operator=<Bar>(b); }
Теперь у нас другая проблема. У меня две перегрузки, только одна из которых может быть использована. Я проезжаю в Baz const &. Все, что я знаю о C++, говорит о том, что это должно закончиться использованием версии без шаблонов, потому что сначала выбираются совпадающие не-шаблоны. Это также похоже на то, что делает gcc. Visual Studio, кажется, не согласен:
error C2666: 'Bar::operator =' : 2 overloads have similar conversions
could be 'const Bar &Bar::operator =(const Bar &)'
or 'const T &Bar::operator =<Baz>(const T &)'
with
[
T=Baz
]
while trying to match the argument list '(Baz, Baz)'
Я искушение верить GCC здесь, и потому, что мое понимание C++ подтверждает это, и потому, что я вообще сторона с НКОЙ, когда он не согласен с Visual Studio, но я не что я об этом беспокоюсь:
В моем не минимальном примере я, честно говоря, не нуждаюсь в том, что оператор присваивания по умолчанию вообще не нужен. Я был бы более чем счастлив, если оператор шаблона выполнит работу - он сделает это правильно. Однако, поскольку VS жалуется на конфликт между шаблоном и автоматически сгенерированным оператором присваивания, я не могу заставить этот шаблон работать вообще. Я пробовал все следующие:
- Выполнение оператора присваивания приватным и невыполненным (не работает, потому что «не все Перегрузки acecssible»)
- Создание его (что приводит к указанной выше ошибки)
- Оставив его (что приводит к ошибке выше оператора присваивания по умолчанию сгенерированные)
- Создание специализации шаблона для этого типа, таким образом, соответствующий оператор назначения по умолчанию точно (явно незаконным в соответствии с компилятором)
У кого-нибудь есть яркие идеи о том, как я могу обойти эту проблему? К сожалению, моя версия VS не поддерживает переопределение C++ 0x «delete» оператора автогенерированного присваивания, поэтому это не вариант, и я не могу думать о других способах обойти эту ошибку.
Зачем вам нужна эта конструкция вообще? Если у вас есть причина объявить класс нецелесообразным, почему вы должны сделать дочерний присваиваемый – Martin
@Martin, это пример минимального воспроизведения. Фактический вариант использования намного сложнее и включает метапрограммирование шаблонов, которое не имеет отношения к вопросу. – Shirik
Возможно, я ошибаюсь: может ли возникнуть проблема со строительством? Обычно оператор = возвращает & для цепочки. Возможно, VS показывает какое-то странное поведение в этом направлении. – Martin