为什么对volatile int的const引用需要static_cast?

时间:2013-12-19 02:55:37

标签: c++ volatile

给出以下代码:

struct Foo { 
    volatile int i; 
};

const int& bar = foo.i; 

我明白了:

error: invalid initialization of reference of type 'const int&' from expression of type 'volatile int'

除非我提供static_cast<volatile int>

2 个答案:

答案 0 :(得分:7)

C ++中类型的“Volatility”与“const-ness”几乎完全相同 - 也就是说,volatile的对象无法分配给非volatile参考,就像

一样
const int i = 3;
int& j = i; // won't work

同样,只能在易失性对象上调用标记为volatile的方法:

struct S
{
    void do_something() volatile {}
    void do_something_else() {}
};

volatile S s;
s.do_something(); // fine
s.do_something_else(); // won't work

方法可以通过“波动率”重载,就像它们可以通过常量重载一样。

在C ++标准中,这些东西被称为 cv-qualifiers ,以强调它们以完全相同的方式工作。 (C99增加了第三个以相同方式工作的restrict,可用作某些C ++编译器中的扩展)。您可以使用const_cast<>更改 cv 限定符 - 不需要功能更强大的static_cast<>

编辑:

为了明确说明,类型可以同时包含constvolatile修饰符,总共有四种可能性:

int i;
const int j;
volatile int k;
const volatile int l;

答案 1 :(得分:3)

const一样,volatile对象只能由volatile引用引用。否则,编译器无法知道通过引用对对象的访问需要是易失性的。

volatile const int& bar = foo.i;
^^^^^^^^
  

除非我提供static_cast<volatile int>

通过添加强制转换来沉默编译器错误并不是一个好主意。这不会为您提供foo.i的引用,而是提供给它的单独副本。

如果您正在做一些非常奇怪的事情,需要对易失性对象进行非易失性引用,则需要const_cast来删除限定符:

const int& weird = const_cast<int&>(foo.i);