gpt4 book ai didi

c++ - 为什么即使 T 的 value_type 是 const,std::is_const::value 也是 'false'?

转载 作者:IT老高 更新时间:2023-10-28 13:00:17 25 4
gpt4 key购买 nike

#include <type_traits>

struct foo;
int main()
{
const foo *bar;

static_assert(std::is_const<decltype(*bar)>::value,
"expected const but this is non-const!");
}

这会导致 static_assert 失败,这是意料之外的。这有点类似于 this question在 const 引用上,但不完全相同。

在我的例子中,取消引用 bar 应该给出一个 const foo 的实例作为它的类型,但 std::is_const 却另有说明。

最佳答案

简而言之,这是因为指向 const 类型的引用或指针不是 const 类型。
请注意 decltype(*bar)不是 const foo ,它是 const foo &他们是真正不同的野兽。


考虑给出的示例 here :

std::cout << std::is_const<const int *>::value << '\n'; // false
std::cout << std::is_const<int * const>::value << '\n'; // true

我们看到 std::is_const<const int *>::value是假的,std::is_const<int * const>::value是真的。
那是因为在 const int *该类型是指向某个 const 的指针,它不是 is_const 所期望的 const 类型(实际上是标准)。在 int * const const 限定符适用于指针类型而不适用于指向的类型,因此该类型是 const 类型,无论它指向什么。
类似的情况适用于 const foo & , 那是对某个 const 的引用。

你可以改用这个来解决:

static_assert(std::is_const<std::remove_reference_t<decltype(*bar)>>::value, "expected const but this is non-const!");

甚至这个,因为你不需要做*bar实际上:

static_assert(std::is_const<std::remove_pointer_t<decltype(bar)>>::value, "expected const but this is non-const!");

在这种情况下,通过 删除指针/引用remove_pointer_t/remove_reference_t您的类型变为 const foo , 那实际上是一个 const 类型。


附带说明,上面的示例使用 C++14-ish std::remove_reference_tstd::remove_pointer_t类型特征。
您可以轻松地将这些代码行转换为 C++11,如下所示:

static_assert(std::is_const<typename std::remove_pointer<decltype(bar)>:: type>::value, "expected const but this is non-const!");

值得一提的是对答案的一些评论以提供更多详细信息:

  • 感谢@DanielFischer 的提问:

    Is there a short explanation why decltype(*bar) is const foo& rather than const foo?

    我不是语言律师,但我想这可以从 [expr.unary.op]/1 中推断出来。 (强调我的):

    The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

    还有 [dcl.type.simple]/4.4 (强调我的):

    otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;

    均指工作草案。

  • 感谢@LightnessRacesInOrbit 的评论。请注意 decltype(*bar)正在 const foo &decltype 的一个有趣的 C++ 怪癖, 自 *bar不是 const foo & .

关于c++ - 为什么即使 T 的 value_type 是 const,std::is_const::value 也是 'false'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41996441/

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