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
>Solution :
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.