c ++ 11 — C ++ 11: преобразование const int * в int * с использованием unordered_set :: push

У меня есть эта проблема преобразования с этим кодом, используя стандарт C ++ 11:

#include<unordered_set>
struct B
{
int x, y;
};

class A
{
struct hash
{
std::size_t operator()( int* const a ) const
{
return std::hash<int>()( *a );
}
};

struct equal_to
{
std::size_t operator()( int* const a, int* const b ) const
{
return std::equal_to<int>()( *a, *b );
}
};

private:
std::unordered_set< int*, hash, equal_to > set;

public:
void push( const B& b )
{
set.insert( &b.x );
}
};

Кто-нибудь знает, почему это? Я могу решить проблему с удалением модификатора «const» в аргументе «push». Но я не хочу этого, потому что аргумент «b» не изменен.

Редактировать .: Мое упрощение кода привело к адресу без ссылки. Я заставил struct B удалить его.

-6

Решение

Ключ от set объявлен как указатель на межд, int*, Но это:

void push( const B& b )
{
set.insert( &b.x );
}

передает адрес константы int, int const*отсюда ошибка компилятора.

Удаление const из аргумента разрешит ошибку компилятора, как если бы тип ключа int const*, но оба эти решения будут:

  • разрешить какую-то другую часть программы, сconst доступ к B экземпляр, который был передан push(), чтобы изменить значение одного из ключей в наборе и нарушить установленный инвариант:

    A a;
    
    B b1{17, 22};
    B b2{30, 22};
    
    a.push(b1);
    a.push(b2);
    
    b1.x = 30;  // set no longer contains unique keys.
    
  • ввести зависимость от set на время жизни объекта, на который ссылается b:

    A a;
    a.push({14, 23}); // a now contains a dangling pointer.
    

Самое безопасное решение — хранить int в качестве ключа см. http://ideone.com/KrykZw для онлайн-демонстрации (спасибо битовая для комментариев).


Возможные решения:

  1. Динамически копировать b.x, Или же,
  2. использование int const* как ключ. Или предпочтительно (избегая явного динамического выделения),
  3. использование int в качестве ключа, а не int* (увидеть http://ideone.com/KrykZw)
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]