从第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
2条答案
按热度按时间5sxhfpxr1#
如果
const
在那里,并且What<int>
碰巧有一个接受The
的构造函数,那么Heck(const What<int> &)
就可以被使用(因为const引用可以绑定到这样的构造函数产生的临时值),检查What<int>
的构造函数需要示例化What<int>
模板。如果没有
const
,那么What<int>
的任何实现都不可能使Heck(What<int> &);
被调用,因此没有必要示例化它。但似乎无论
What<int>
具有什么构造函数,Heck(The)
重载都将优先,因此严格地说,在此特定情况下,此示例化似乎是不必要的。bf1o4zei2#
如果
What
有What::What(The)
这样的构造函数,则隐式转换Heck(What(the))
对Heck::Heck(const What&)
有效,但对Heck::Heck(What&)
无效。在调用
Heck(the)
的重载解析期间,对可行函数的搜索消除Heck::Heck(What&)
但不消除Heck::Heck(const What&)
,这被延续到对最佳可行函数的搜索,这需要示例化What
。