Home > Software engineering >  Why does removing 'const' on line 12 of this program stop the class from being instantiate
Why does removing 'const' on line 12 of this program stop the class from being instantiate

Time:01-18

Removing const from line 12 prevents the class What from being instantiated during compilation. I do not expect What to ever be instantiated, regardless of constness in the declaration. This is consistent between clang, gcc and MSVC so I assume it is standard. Marking the constructor explicit also does not prevent the instantiation. What am I not understanding here? Why does constness make a difference?

template <typename T> constexpr bool just_false() { return false; }

template<typename T>
class What {
    static_assert(just_false<T>(), "Why was this class instantiated?");
};

struct The {};

struct Heck {
    Heck(The) {}
    Heck(const What<int>&); // Removing 'const' from this line stops 'What<int>' from being instantiated
};

int main() {
    The the;
    Heck{the};
}

The just_false incantation is just to prevent the static assert from always triggering regardless of instantiation.

Compiler explorer link: https://godbolt.org/z/8cETcfss5

CodePudding user response:

If const is there, and What<int> happens to have a constructor taking The, that would allow Heck(const What<int> &) to be used (because a const reference can bind to a temporary produced by such constructor). Checking for that constructor of What<int> requires instantiating What<int>.

If there is no const, no implementation of What<int> could possibly make Heck(What<int> &); be called, so there's no point in instantiating it.


But it seems that no matter what constructor What<int> has, the Heck(The) overload would take precedence, so strictly speaking, this instantiation seems to be unnecessary in this specific case.

CodePudding user response:

If What had a constructor such as What::What(The), then the implicit conversion Heck(What(the)) would be valid for Heck::Heck(const What&) but not for Heck::Heck(What&).

During overload resolution for the call Heck(the), the search for viable functions eliminates Heck::Heck(What&) but does not eliminate Heck::Heck(const What&), which gets carried over to the search for a best viable function, which requires instantiating What.

  • Related