std :: set с помощью указателей классов. Как управлять вставкой [дубликат]

Чтобы округлить число до разрешения, наилучшим способом является следующий, который может работать с любым разрешением (0,01 для двух десятичных знаков или даже других шагов):

>>> import numpy as np
>>> value = 13.949999999999999
>>> resolution = 0.01
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
13.95

>>> resolution = 0.5
>>> newValue = int(np.round(value/resolution))*resolution
>>> print newValue
14.0
326
задан Drew Noakes 8 May 2012 в 12:51
поделиться

4 ответа

Объекты в std::set сохраняются как const StudentT. Поэтому, когда вы пытаетесь вызвать getId() с объектом const, компилятор обнаруживает проблему, в основном вы вызываете функцию не-const-члена в const-объекте, которая не разрешена, поскольку не-константные функции-члены не делают НИКАКИХ ОБЯЗАТЕЛЬНО не изменить объект; поэтому компилятор должен сделать предположение safe , что getId() может попытаться изменить объект, но в то же время он также замечает, что объект является const; поэтому любая попытка изменить объект const должна быть ошибкой. Следовательно, компилятор генерирует сообщение об ошибке.

Решение прост: сделайте функции const такими как:

int getId() const {
    return id;
}
string getName() const {
    return name;
}

Это необходимо, потому что теперь вы можете вызывать getId() и getName() для объектов const как:

void f(const StudentT & s)
{
     cout << s.getId();   //now okay, but error with your versions
     cout << s.getName(); //now okay, but error with your versions
}

В качестве побочного элемента вы должны реализовать operator< как:

inline bool operator< (const StudentT & s1, const StudentT & s2)
{
    return  s1.getId() < s2.getId();
}

. Параметры примечаний теперь const.

378
ответ дан Tomer 24 August 2018 в 23:00
поделиться

На самом деле стандарт C ++ (т. е. C ++ 0x draft ) говорит (tnx to @Xeo & amp; @Ben Voigt для указания этого на меня):

23.2 .4 Ассоциативные контейнеры 5 Для set и multiset тип значения совпадает с типом ключа. Для карты и мультимапа он равен паре. Ключи в ассоциативном контейнере неизменяемы. 6 итератор ассоциативного контейнера относится к категории двунаправленного итератора. Для ассоциативных контейнеров, где тип значения совпадает с типом ключа, оба итератора и const_iterator являются постоянными итераторами. Не указано, является ли итератор и const_iterator одним и тем же типом.

Итак, реализация Dinkumware VC ++ 2008 ошибочна.


Старый ответ:

Вы получили эту ошибку, потому что в некоторых реализациях std lib set::iterator совпадает с set::const_iterator.

Например, libstdc ++ (поставляется с g ++) имеет его (см. здесь для всего исходного кода):

typedef typename _Rep_type::const_iterator            iterator;
typedef typename _Rep_type::const_iterator            const_iterator;

И в SGI docs указывает:

iterator       Container  Iterator used to iterate through a set.
const_iterator Container  Const iterator used to iterate through a set. (Iterator and const_iterator are the same type.)

С другой стороны, VC ++ 2008 Express компилирует ваш код, не жалуясь, что вы вызываете методы non const на set::iterator s.

3
ответ дан Eugen Constantin Dinca 24 August 2018 в 23:00
поделиться

Функции членов, которые не изменяют экземпляр класса, должны быть объявлены как const:

int getId() const {
    return id;
}
string getName() const {
    return name;
}

В любое время, когда вы видите «отбрасывает квалификаторы», речь идет о const или volatile.

67
ответ дан Fred Larson 24 August 2018 в 23:00
поделиться

Позвольте мне привести более подробный пример. Что касается ниже структуры:

struct Count{
    uint32_t c;

    Count(uint32_t i=0):c(i){}

    uint32_t getCount(){
        return c;
    }

    uint32_t add(const Count& count){
        uint32_t total = c + count.getCount();
        return total;
    }
};

Как вы видите выше, IDE (CLion) даст подсказки Non-const function 'getCount' is called on the const object. В методе add count объявлен как объект const, но метод getCount не является методом const, поэтому count.getCount() может изменять члены в count.

Ошибка компиляции, как показано ниже (основное сообщение в моем компиляторе):

error: passing 'const xy_stl::Count' as 'this' argument discards qualifiers [-fpermissive]

Чтобы решить эту проблему, вы можете:

  1. изменить метод uint32_t getCount(){...} на uint32_t getCount() const {...}. Таким образом, count.getCount() не будет изменять элементы в count.

или

  1. изменить uint32_t add(const Count& count){...} на uint32_t add(Count& count){...}. Поэтому count не заботится об изменении членов в нем.

Что касается вас, объекты в std :: set сохраняются как const StudentT, но метод getId и getName не const, поэтому вы указываете вышеприведенную ошибку.

Вы также можете увидеть этот вопрос Значение 'const' последним в объявлении функции класса? для более подробно.

0
ответ дан Jayhello 24 August 2018 в 23:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: