#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
. 这有点类似于const引用上的this question但不完全相同 .
在我的情况下,取消引用 bar
应该给出一个 const foo
的实例作为其类型,但 std::is_const
却说不然 .
1 回答
不久之后,因为引用或指向const类型的指针不是const类型 .
请注意
decltype(*bar)
不是const foo
,它是const foo &
并且它们实际上是不同的野兽 .考虑给出here的示例:
我们看到
std::is_const<const int *>::value
是假的,std::is_const<int * const>::value
是真的 .那是因为在
const int *
中,类型是指向const的指针,这不是is_const
(实际上是标准)所预期的const类型 . 在int * const
中,const限定符适用于指针类型,而不适用于指向的类型,因此类型是常量类型,无论它指向什么 .类似的东西适用于
const foo &
,这是对const的引用 .您可以使用此解决方案:
或者甚至是这样,因为你实际上不需要做
*bar
:在这种情况下,通过使用
remove_pointer_t
/remove_reference_t
删除指针/引用,您的类型变为const foo
,这实际上是一个const类型 .作为旁注,上面的示例使用C 14-ish
std::remove_reference_t
和std::remove_pointer_t
类型特征 .您可以轻松地将这些代码行转换为C 11,如下所示:
值得一提的是给答案的一些评论,以提供更多细节:
我不是语言律师,但我想这可以从[expr.unary.op]/1(强调我的)推断出来:
并且[dcl.type.simple]/4.4(强调我的):
两者都提到了工作草案 .
decltype(*bar)
是const foo &
是decltype
的一个有趣的C怪癖,因为*bar
不是const foo &
.