查看 libstdc++ 源代码,我发现了以下declval
实现:
template<typename _Tp, typename _Up = _Tp&&>
_Up __declval(int); // (1)
template<typename _Tp>
_Tp __declval(long); // (2)
template<typename _Tp>
auto declval() noexcept -> decltype(__declval<_Tp>(0));
这个实现是由 Eric Niebler 作为编译时优化提出的:他解释说重载解析比模板实例化更快。
但是,我无法理解它是如何工作的。具体来说:
- 在(1)中,为什么使用
_Up
比仅仅返回更好_Tp&&
? - 似乎从未使用过重载(2)。为什么需要它?
这一切如何防止模板实例化,而不是最天真的实现:
template<typename T>
T&& declval() noexcept;