非静态常量成员,不能使用默认赋值运算符。

52

我正在扩展的一个程序经常使用 std::pair<>

在我的代码中有一个点,编译器会抛出一个相当大的错误:

  

非静态 const 成员 'const Ptr std::pair, const double * ::first' 无法使用默认赋值运算符

我不是很确定这是什么意思?哪些方法缺失于 Ptr 类中?

导致此问题的原始调用如下:

vector_of_connections.pushback(pair(Ptr<double,double>,WeightValue*));

在将一个 std::Pair<Ptr<double,double>, WeightValue*> 放入一个向量中时,其中的 WeightValue* 是从大约3个函数之前的一个常量变量,而 Ptr<double,double> 取自一个可以工作于另一个向量的迭代器。

为了以后的参考,Ptr<double,double> 是指向 Node 对象的指针。


你在代码中具体做了什么?我没有看到任何赋值操作。 - rjh
没有告诉我们太多信息。能否再发一些内容? - dirkgently
你能具体说明一下“Ptr”吗? - JaredPar
对不起,我会尝试修改。因为我正在处理的代码非常复杂,所以很难判断我的问题是否足够清晰。 - Ed James
1
你又贴了一些伪代码。同时也把另一个迭代器的类型和获取方式一并贴上...不要试图注释代码。你很可能会在注释中犯同样的错误,但是请贴上真实的代码。 - Johannes Schaub - litb
1
不行,那个不是我的粘贴。我可以给你一个理论的概述,但是没有一些法律上的可疑性就只能到此为止了。 总之,它大约有15个函数调用,所使用的所有类都是自定义的,所以这里可能会有很多代码。 - Ed James
4个回答

89
你有这样一个情况:

你有这样一个情况:

struct sample {
    int const a; // const!

    sample(int a):a(a) { }
};

现在,您将其用于某些需要sample可分配的上下文中-在容器(例如map、vector或其他容器)中可能会出现这种情况。这将失败,因为隐式定义的复制赋值运算符执行以下操作:

// pseudo code, for illustration
a = other.a;

但是a是const的!你需要将其变为非const。这并不会有什么影响,因为只要你不改变它,它仍然是逻辑上的const :) 你可以通过引入一个合适的operator=来解决问题,使编译器不会隐式地定义一个。但这很糟糕,因为你将无法更改const成员。 因此,虽然有operator=,但仍然不可分配!(因为复制和分配值不相同!):

struct sample {
    int const a; // const!

    sample(int a):a(a) { }

    // bad!
    sample & operator=(sample const&) { }
};

然而在你的情况下,显然问题似乎出现在std::pair<A, B>中。请记住,std::map是以它所包含的键进行排序的。因此,你不能更改其键,因为这可能会使映射的状态无效。因此,以下内容成立:

typedef std::map<A, B> map;
map::value_type <=> std::pair<A const, B>

也就是说,它禁止更改其中包含的键!因此,如果你这样做了:

*mymap.begin() = make_pair(anotherKey, anotherValue);

地图会向你抛出错误,因为在一些存储在地图中的值对中,::first成员具有const限定类型!


14

我遇到了同样的问题,并且找到了这个页面。

http://blog.copton.net/archives/2007/10/13/stdvector/index.html

以下内容摘自该页面:

请注意,这不是GNU特有的问题。ISO C++标准要求T具有赋值运算符(参见第23.2.4.3节)。我仅以GNU STL实现的示例说明了可能导致的问题。


2
FYI,看起来blog.copton.net已经无法访问了 :/ - jstm

2
据我所知,你的某个地方可能有以下类似的内容:

...

// for ease of reading 
typedef std::pair<const Ptr<double, double>, const double*> MyPair;

MyPair myPair = MAKEPAIR(.....);
myPair.first = .....;

因为MyPair的成员是const类型,所以你不能对它们进行赋值。


-1

至少要提到编译器抱怨的是哪个对象。很可能你缺少了一个自定义赋值成员。如果没有,那么默认的成员就会启动。可能,在该类中还有一个const成员(被分配的对象),由于const成员不能更改,因此出现了错误。

另一种方法:既然它是一个类的const,我建议你将其更改为static const,如果这有意义的话。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接