c++ 为什么从构造函数参数中删除'const'会阻止类被示例化?

o75abkj4  于 2023-01-22  发布在  其他
关注(0)|答案(2)|浏览(115)

从第12行删除const可以防止类What在编译期间被示例化。我不希望What被示例化,不管声明中的常量如何。gcc和MSVC,所以我假设它是标准的。标记构造函数explicit也不会阻止示例化。我在这里不理解什么?为什么坚定性会产生影响?

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};
}

just_false咒语只是为了防止静态Assert总是触发,而不管示例化如何。
编译器资源管理器链接:https://godbolt.org/z/8cETcfss5

5sxhfpxr

5sxhfpxr1#

如果const在那里,并且What<int>碰巧有一个接受The的构造函数,那么Heck(const What<int> &)就可以被使用(因为const引用可以绑定到这样的构造函数产生的临时值),检查What<int>的构造函数需要示例化What<int>模板。
如果没有const,那么What<int>的任何实现都不可能使Heck(What<int> &);被调用,因此没有必要示例化它。
但似乎无论What<int>具有什么构造函数,Heck(The)重载都将优先,因此严格地说,在此特定情况下,此示例化似乎是不必要的。

bf1o4zei

bf1o4zei2#

如果WhatWhat::What(The)这样的构造函数,则隐式转换Heck(What(the))Heck::Heck(const What&)有效,但对Heck::Heck(What&)无效。
在调用Heck(the)的重载解析期间,对可行函数的搜索消除Heck::Heck(What&)但不消除Heck::Heck(const What&),这被延续到对最佳可行函数的搜索,这需要示例化What

相关问题