3

Consider the following code:

struct A {
};
struct B {
    A a;
    bool operator == (const B& other) const = default;
};

clang gives a nice warning :

warning: explicitly defaulted equality comparison operator is implicitly deleted [-Wdefaulted-function-deleted] bool operator == (const B& other) const = default;

But I wonder why is this code even accepted by the standard. I would assume that if somebody defaults the operator == in his nontemplate struct/class his intention is never to get deleted operator ==.

But this is C++ with a million corner cases so there might a good reason. Maybe not to special case templates?

But clang is smart enough to not warn on this code...

struct A {
};

template<typename T>
struct TS{
    T t;
    bool operator == (const TS& other) const = default;
};
int main() {
    TS<int> ti;
}

... so in theory standard could do the same.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • 4
    Maybe for consistency with explicitly defaulted constructors and assignment operators? – HolyBlackCat Feb 04 '21 at 18:21
  • 2
    Generic code, I reckon. A class template may default it. Its specializations shouldn't be ill-formed upon instantiation if the operator is never used (like all ill-formed member function bodies of class templates). – StoryTeller - Unslander Monica Feb 04 '21 at 18:30
  • @StoryTeller-UnslanderMonica maybe I am misunderstanding you, but clang is NOT issuing a warning in template case, I consider that a feature not a bug since it is silly to diagnose templates just on known uses. – NoSenseEtAl Feb 04 '21 at 19:02
  • No it is I who simply missed the word "no". – StoryTeller - Unslander Monica Feb 04 '21 at 19:05
  • @StoryTeller-UnslanderMonica not really nice English, will fix – NoSenseEtAl Feb 04 '21 at 19:19
  • Nitpick: The spaceship operator isn't involved here (though the C++20 changes that introduced it are related to the changes that allow defaulting `operator==`). Did you mean to use the spaceship operator, `operator<=>`, or did you mistag? – ShadowRanger Feb 04 '21 at 19:39
  • @ShadowRanger AFAIK there is no nice tag for c++ comparison operator changes in c++20... and this is the closes I know of beside useless generic tags, e.g. equality or comaprisons... – NoSenseEtAl Feb 04 '21 at 19:42
  • 1
    @NoSenseEtAl: You're right. The defaulted-functions tag definitely applies, and I've made a default-comparisons tag as well (matching the existing default-constructor for the other common case of defaulting, and broader that questions specific to the spaceship operator). spaceship-operator is related, but not super-helpful in terms of tying to other questions (most of those tagged with it are really asking about `operator<=>` specifically), so I removed it. – ShadowRanger Feb 04 '21 at 19:51

1 Answers1

4

In a template, you may want == if it can exist, and otherwise not.

The same technique is used for copy/move/assign special member functions; =default; can delete the member function as well.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • I can see why the OP is confused though. The cases you mention can be implicitly deleted for two reasons: 1) A paired function is defined (e.g. copy constructor defined deletes implicit move), or 2) A member prevents the function from being generated (e.g. `std::unique_ptr` member suppresses implicit copy constructor). `= default` never defines the function for #2, but #2 doesn't come up as often with the other use cases of `= default` (where the user often knows they have copy/moveable attributes). The OP is trying to use `= default` for case #2 based on experience with (working) case #1. – ShadowRanger Feb 04 '21 at 19:37