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
.