了解declval优化的实现

时间:2019-05-19 21:23:16

标签: c++ c++11 language-lawyer template-instantiation declval

查看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的此实现was proposed是编译时优化的方法:他解释说,重载解析比模板实例化要快。

但是,我不明白它是如何工作的。具体来说:

  1. 在(1)中,为什么使用_Up比仅返回_Tp&&更好?
  2. 似乎从未使用过重载(2)。为什么需要它?

与最幼稚的实现相反,这一切如何阻止模板实例化:

template<typename T>
T&& declval() noexcept;

1 个答案:

答案 0 :(得分:11)

幼稚的实现并不完全正确。根据标准,declval定义为([declval]):

  

template <class T> add_rvalue_reference_t<T> declval() noexcept;

,对于add_rvalue_reference<T>,标准读取为([meta.trans.ref]):

  

如果T命名可引用类型,则成员typedef type命名   T&&;否则,type命名为T

不可引用类型的示例是void。在这种情况下,由于SFINAE,将使用第二个重载。

关于第一个问题,我看不出任何特殊原因。 _Tp&&应该可以正常工作。