Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does removing 'const' from the constructor parameter stop the class from being instantiated?

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

like image 934
Dave Magnets Avatar asked Aug 31 '25 20:08

Dave Magnets


1 Answers

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 the What<int> template.

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.

like image 160
HolyBlackCat Avatar answered Sep 05 '25 03:09

HolyBlackCat