1

Consider the following code:

class Foo { public:
    int const i;
    Foo() : i(0) {}
};

void test() {
    Foo       a;
    Foo const b;
    a = b; //Failure here; `Foo::operator=` implicitly deleted
}

The indicated line fails because the operator= ordinarily generated by the compiler cannot be generated: .i is marked const. This is good and expected.

The programmer can generate their own operator=, so long as it does not change .i. E.g. this method does nothing:

Foo& operator=(Foo const& other) { 
    return *this;
}

But now, suppose I want to be more-general. I templatize the method:

template <typename TypeOther>
Foo& operator=(TypeOther const& other) {
    return *this;
}

Suddenly, I get back the original failing behavior (tested Clang, GCC, and MSVC)! It seems that, even though the default operator= is not generated, it participates in overload resolution and therefore is selected instead of the template variant.

  1. Why is the implicit operator is being selected even though it does not exist (i.e, is it as if I had just written and deleted it myself—that is, it exists but is forbidden)?
  2. How I can work around this to make my template operator= be selected for any type?
geometrian
  • 14,775
  • 10
  • 56
  • 132
  • *" does not exist"* - Is the wrong frame of mind. It does exist, as deleted (`= delete;` is in fact a definition). It's overload resolution choosing a deleted function that causes an error. That's how the standard defines it. – StoryTeller - Unslander Monica Feb 03 '19 at 09:50

0 Answers0