【问题标题】:Can't assign an object to a volatile object无法将对象分配给易失性对象
【发布时间】:2011-06-06 08:51:57
【问题描述】:

我想将一个对象分配给同一类型的 volatile 对象,但由于编译器错误而未能这样做。如何更改程序来制作它?除了让它工作,为什么我不能直接做?

我在这里使用 Visual Studio 2010 作为编译器。

class A
{
public:
};

int _tmain()
{
    A a;
    volatile A va;
    va = a;        // compiler error:C2678 here
    return 0;
}

【问题讨论】:

标签: c++


【解决方案1】:

您需要使用volatile 限定符为A 定义一个赋值运算符函数。

class A
{
    public:

    volatile A& operator = (const A& a) volatile
    {
      // assignment implementation
    }
};

如果您没有为类定义赋值运算符,C++ 将创建一个默认的赋值运算符A& operator = (const A&);。但它不会创建带有volatile 限定符的默认赋值运算符,因此您需要显式定义它。

【讨论】:

  • 谢谢。我认为返回类型应该是volatile A&
  • 如果struct类型来自平台头文件,你不控制如何干净地解决这个问题?
  • 请将 cv 限定符写在正确的位置,在类型名称之后。尽管有语法,但它的引用是 cv 限定的:A volatile& 不是基本类型。
  • 这不是真的。 A volatile& 和volatile A& 的意思完全一样,都应用volatile 作为参考。 volatile A* 和 A* volatile 之间会有所不同,尽管您不能将后者与引用类型一起使用。
【解决方案2】:

我也遇到过同样的问题。例如:

struct A { int i; }
volatile A a;
A b;
a = b;   // C2678 here.

我找到了这个方法来解决它:

const_cast<A &>(a) = b;

【讨论】:

  • 你不能抛弃易失性,你的代码有未定义的行为。
  • @JamesJohnston 对于不控制结构定义的情况,您有更简洁的解决方案吗? (就像它来自系统 API 标头一样?)我已经采用了这个解决方案。我不相信这种行为是未定义的,因为这不是 const 限定符。无论是否为volatile,都允许对对象赋值,并且volatile 不是一种特殊的访问;限定符只影响优化(两个或多个访问是否合并为一个)。在我的特定情况下,这并不重要。这不可能是个问题。
  • 对不起,我认为你错了,行为未定义。请参阅stackoverflow.com/a/7368038/562766 -- 来自 C11:“尝试通过使用具有非 volatile 限定类型 (6.7.3) 的左值来引用使用 volatile 限定类型定义的对象” --- 在示例中上面,volatile是从"a"中抛弃的,原来是用volatile定义的,然后赋值。您的代码的正确性现在取决于优化器。
  • @JamesJohnston 你对 Kaz 提出的问题有什么建议吗,即需要执行一项你无法控制类定义的作业?
猜你喜欢
  • 1970-01-01
  • 2017-11-01
  • 2014-04-05
  • 2020-05-22
  • 2021-06-30
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多