gpt4 book ai didi

c++ - libstdc++对std::declval的实现问题

转载 作者:行者123 更新时间:2023-12-04 14:43:51 25 4
gpt4 key购买 nike

不像 libc++MSVC-STL仅声明 std::declval 的函数签名, libstdc++std::declval 定义函数体,并使用 static_assert在内部确保它必须在未评估的上下文中使用:

template<typename _Tp, typename _Up = _Tp&&>
_Up
__declval(int);

template<typename _Tp>
_Tp
__declval(long);

template<typename _Tp>
auto
declval() noexcept -> decltype(__declval<_Tp>(0));

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

template<typename _Tp>
auto
declval() noexcept -> decltype(__declval<_Tp>(0)) {
static_assert(__declval_protector<_Tp>::__stop,
"declval() must not be used!");
return __declval<_Tp>(0);
}
当我们尝试评估 std::declval 的返回值时, 这个 static_assert将被触发:
auto x = std::declval<int>(); // static assertion failed: declval() must not be used!
但是我发现在这个实现中,下面的代码也会被拒绝,因为 static_assert失败( godbolt ):
#include <type_traits>

template<class T>
auto type() { return std::declval<T>(); }

using T = decltype(type<int>());
但似乎 std::declval仍然在未评估的上下文中使用,因为我们尚未实际评估它。
上面的代码格式正确吗?如果是这样,它是一个库实现错误吗?标准是如何规定的?

最佳答案

该示例格式错误,因为 std::declval 的限制实际上是在表达式 where declval被命名,而不是根据抽象虚拟机是否会实际评估它的调用。std::declval上的要求是 [declval].2

Mandates: This function is not odr-used ([basic.def.odr]).


其中“授权”是指( [structure.specifications]/(3.2) )

Mandates: the conditions that, if not met, render the program ill-formed.


[basic.def.odr]/7 :

A function is odr-used if it is named by a potentially-evaluated expression or conversion.


而在 [basic.def.odr]/2 :

An expression or conversion is potentially evaluated unless it is an unevaluated operand ([expr.prop]), a subexpression thereof, or a conversion in an initialization or conversion sequence in such a context.


注意表达式 type<int>()最后一行是一个未计算的操作数。但是明显的表达 std::declval<T>()type 的实例化定义中可能被评估。忽略这一点并不重要,它实际上不会被评估。
所以实际上 libc++ 和 MSVC-STL 实现是不正确的,因为除非另有说明,否则应该诊断格式错误的程序。

关于c++ - libstdc++对std::declval的实现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68590453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com