【问题标题】:cv-qualified struct's member is not similarly cv-qualifiedcv 限定结构的成员不是类似 cv 限定的
【发布时间】:2015-10-22 21:38:39
【问题描述】:

根据这个answer,下面的代码应该编译没有错误:

#include <type_traits>

namespace
{

struct A { int i; };

volatile A a{};
static_assert(std::is_volatile< decltype(a) >{});
static_assert(std::is_volatile< decltype(a.i) >{});

}

但是有一个硬错误:

main.cpp:10:1: error: static_assert failed
static_assert(std::is_volatile< decltype(a.i) >{});
^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

Live example with clang 3.6.0.

这是一个clang错误还是我错过了一些实质性的东西?

附加:

#include <type_traits>

namespace
{

struct A { int i; };

const A a{};
static_assert(std::is_const< decltype(a) >{});
static_assert(std::is_const< decltype(a.i) >{});

}

后一个代码 sn-p 的行为完全相同。

附加:

static_assert(std::is_volatile< std::remove_pointer_t< decltype(&a.i) > >{});

不会导致错误。

【问题讨论】:

标签: c++ c++11 clang c++14 typetraits


【解决方案1】:

这是正确的行为;当前的decltype 没有测试您认为它测试的内容。如果你想测试volatile-ness,你必须改变你的decltype

可以复制一个值并删除volatile-ness。但是引用必须是volatile对volatile的引用。

int foo() {
    int i = a.i;            // volatile not needed
    volatile int &i = a.i;  // volatile needed
}

decltype a.i 视为右值,而不是左值,执行decltype 默认执行的操作,并且正在执行“幼稚”文本分析并报告@ 的类型源代码中写的987654330@;因此,decltype(a.i)int

() 放在decltype 中的表达式周围会改变它的行为(对于这类问题,通常以好的方式),在适当的时候给我们一个左值。因此,decltype(( a.i )) 就是volatile int &amp;

现在,您可能认为is_volatile&lt; volatile int &amp; &gt;::value 是真的。但事实并非如此。我们需要先删除引用,然后才能测试 volatile-ness。

static_assert(std::is_volatile< std::remove_reference_t<decltype((a.i))> >{});

最后,根据is_volatilevolatile int &amp; 并非易失性,您可能会感到惊讶。但我想这是因为引用真的很像指针——而且引用中的“指针”不是易失的,即使指向的对象是易失的。无论如何,这是我的理论。 const int&amp;也不满足is_const

【讨论】:

  • 引用的语义和dereferenced pointer差不多。
  • @T.C.,我的错。我没有正确阅读我的测试结果。我想我只是假设它会是is_const 并且没想到证据会与我相矛盾。不过我觉得这真的很奇怪!
  • 感谢大家的反馈!这个答案发生了很大变化。很多时候都错了,现在应该还不错。 (我仍然不完全满意 :-))
  • "[...] 并且正在执行“天真”文本分析并报告源代码中所写的 A::i 的类型;因此,decltype(a.i) 是 int。”为什么是(正式地)?
  • @black,我对decltype 的了解大部分来自the Wikipedia article。如果可以改进,我很乐意更改它,或者让其他人更改它;但我不是语言律师。另外,也许这里没有必要完全解释decltype。我认为,告诉 OP 没有括号并没有达到 OP 的预期就足够了。
猜你喜欢
  • 1970-01-01
  • 2013-11-17
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
相关资源
最近更新 更多