Нестатический константный член, не может использовать оператор присваивания по умолчанию - PullRequest
43 голосов
/ 11 марта 2009

Расширяемая программа использует 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.

Ответы [ 4 ]

77 голосов
/ 11 марта 2009

У вас есть такой случай:

struct sample {
    int const a; // const!

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

Теперь вы используете это в некотором контексте, который требует присваивания sample - возможно в контейнере (например, карта, вектор или что-то еще). Это не удастся, потому что неявно определенный оператор присваивания копии делает что-то вроде этой строки:

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

Но a является постоянным! Вы должны сделать это неконстантным. Это не больно, потому что до тех пор, пока вы его не измените, оно по-прежнему логически константно :) Вы можете решить проблему, введя подходящий 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 имеет тип с постоянным типом!

14 голосов
/ 07 декабря 2010

Я столкнулся с той же проблемой и наткнулся на эту страницу.

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

Со страницы:

Пожалуйста, обратите внимание, что здесь нет особых проблем с GNU. Стандарт ISO C ++ требует, чтобы T имел оператор присваивания (см. Раздел 23.2.4.3). Я только что показал на примере реализации STL в GNU, к чему это может привести.

1 голос
/ 11 марта 2009

Насколько я могу судить, где-то у вас есть что-то вроде:

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

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

Поскольку члены MyPair являются постоянными, вы не можете назначать их.

0 голосов
/ 11 марта 2009

По крайней мере, укажите, на какой объект жалуется компилятор. Скорее всего, вам не хватает пользовательского назначения назначения. Если у вас его нет, включается по умолчанию. Возможно, у вас также есть член const в этом классе (чьи объекты назначаются), и, поскольку член const не может быть изменен, вы нажимаете эту ошибку.

Другой подход: поскольку это класс const, я предлагаю изменить его на static const, если это имеет смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...