std :: declval如何工作?

Mat*_* F. 4 c++ c++11

有人可以解释一下std :: declval是如何工作的吗?我在gcc headers/type_traits(第2248-2262行)中找到了这个实现,这是为了提高可读性而稍微清理一下:

template<typename _Tp>
struct __declval_protector
{
    static const bool __stop = false;
    static typename add_rvalue_reference<_Tp>::type __delegate();
};

template<typename _Tp>
typename add_rvalue_reference<_Tp>::type
declval ()
{
    static_assert(__declval_protector<_Tp>::__stop, "declval() must not be used!");
    return __declval_protector<_Tp>::__delegate();
}
Run Code Online (Sandbox Code Playgroud)

我不理解该部分return __declval_protector<_Tp>::__delegate(),是否为类型为T的Rvalue引用调用默认初始值设定项?另外我不明白为什么每次打电话都没有调用,因为它总是假的(它如何区分未评估的上下文和评估的上下文?).static_assertdeclval__stop

编辑: 从我现在的理解,所有这些东西相当于:

template<typenam _Tp>
struct __declval_protector
{
    const bool __stop = false;
};

template<typename _Tp>
typename add_rvalue_reference<_Tp>::type
mydeclval ()
{
    static_assert(__declval_protector<_Tp>::__stop, "declval() must not be used!");
}
Run Code Online (Sandbox Code Playgroud)

但当然编译器会发出我们不返回任何内容的问题.

Ker*_* SB 17

我不明白为什么每次调用declval都不会调用static_assert,因为__stop总是为false

你的前提是错的.静态断言真的叫你每次通话时间declval.诀窍是你绝不能打电话declval.它必须仅用于未评估的上下文中.这就是静态断言存在的原因.

  • @Mattia F.如果static_assert不依赖于模板参数,则会触发模板是否实例化. (4认同)
  • @TC 如果我们在这些情况下允许“static_assert(false, ...)”,那就简单多了。 (2认同)