关于c ++:非静态const成员,不能使用默认赋值运算符

Non-static const member, can't use default assignment operator

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

我的代码中有一点编译器抛出了一个相当大的:

Non-static const member, 'const Ptr std::pair, const double*>::first' can't use default assignment operator

我真的不确定这是指什么?ptr类中缺少哪些方法?

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

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

它把一个std::Pair, WeightValue*>放到一个向量上,其中WeightValue*是一个来自3个函数的常量变量,而Ptr是从一个迭代器中提取的,该迭代器在另一个向量上工作。

为了将来参考,Ptr是指向Node对象的指针。


你有这样一个案子:

1
2
3
4
5
struct sample {
    int const a; // const!

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

现在,您可以在某些上下文中使用它,这些上下文要求sample可以在容器(如地图、向量或其他东西)中分配。这将失败,因为隐式定义的复制分配运算符沿着这一行执行某些操作:

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

但是以东十一〔三〕是警察!你必须让它成为非常量。它不会造成伤害,因为只要你不改变它,它在逻辑上仍然是常量:)你可以通过引入一个合适的operator=来解决这个问题,使编译器不会隐式地定义一个。但那很糟糕,因为你不能改变你的警察。因此,有一个运算符=,但仍然不可赋值!(因为副本和分配的值不相同!)以下内容:

1
2
3
4
5
6
7
8
struct sample {
    int const a; // const!

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

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

然而,在您的案例中,明显的问题在于std::pair中。记住,std::map是根据它所包含的键进行排序的。因此,您不能更改其键,因为这样很容易使映射的状态无效。因此,以下观点成立:

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

也就是说,它禁止更改它所包含的密钥!所以如果你这样做的话

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

映射向您抛出一个错误,因为在映射中存储的某个值对中,::first成员具有常量限定类型!


我也遇到了同样的问题,我看到了这一页。

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

从页面:

Please note that this is no GNU specific problem here. The ISO C++ standard requires that T has an assignment operator (see section 23.2.4.3). I just showed on the example of GNU's STL implementation where this can lead to.


据我所知,有些地方你有:

1
2
3
4
5
// for ease of reading
typedef std::pair<const Ptr<double, double>, const double*> MyPair;

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

因为mypair的成员是const,所以不能分配给它们。


至少要提到编译器抱怨的对象。很可能您缺少自定义分配成员。如果你没有,默认的就会出现。很可能,您在该类中也有一个常量成员(其对象正在被分配),并且由于不能更改常量成员,所以您遇到了该错误。

另一种方法:因为它是一个类const,所以我建议您将它改为static const,如果这有意义的话。