Можно ли "закрепить" поле `std :: pair` без хаков? - PullRequest
4 голосов
/ 03 сентября 2010

В C ++ компилируется следующий код:

std::pair <int, int>  x;
static_cast <std::pair <const int, int>*> (&x);

выдает ошибку:

error: invalid static_cast from type ‘std::pair<int, int>*’ to type ‘std::pair<const int, int>*’

Я более или менее понимаю, почему это происходит, поскольку cv-квалификация типа в списке параметров шаблона в принципе может дать "несовместимый" результат. И даже если в этом случае это не так, компилятор не может это узнать.

В любом случае, существует ли нехакский способ выполнить это преобразование ? Я опасаюсь использовать reinterpret_cast для чего угодно, так как раньше я сталкивался с проблемами типа. Кроме того, я не могу использовать временные файлы, так как это в коде, критичном к производительности.

EDIT:

Вот что я делаю. Я реализую пользовательский интерфейс контейнера, совместимый с std::unordered_map. Из-за этого его value_type должен быть pair <const key_type, mapped_type>. Для некоторой оптимизации мне нужно внутренне сохранить значения как pair <key_type, mapped_type>, без const. Однако, если я это сделаю, я не смогу (без reinterpret_cast) реализовать итераторы над контейнером, поскольку они должны возвращать ссылки на значения, и у меня есть только ссылки на эти неконстантные пары.

Ответы [ 2 ]

1 голос
/ 03 сентября 2010

Это не приведение, но вы можете сделать следующее:

std::pair<int, int>  x;
std::pair<const int, int> y( x );

Это должно работать в соответствии с §20.2.2 / 4.

0 голосов
/ 03 сентября 2010

Как насчет этого:

template< typename T1, typename T2 >
struct ref_pair {
public:
    typedef const T1 first_type;
    typedef T2 second_type;

    ref_pair(first_type& f, second_type& s) : f_(f), s_(s) {}

    first_type& first() {return *f_;}
    second_type& second() {return *s_;}
private:
    first_type* f_;
    second_type* s_;
};

Я знаю, это другое, это функции. Если вы действительно в отчаянии, вы можете превратить first и second в объекты некоторого типа прокси, которые оценивают задержку *f_ и *s_.
Тем не менее, в конце концов, пользователи всегда могут заметить разницу.


Я думаю, что следующее будет достаточно безопасным и переносимым, хотя, конечно, с reinterpret_cast ничего не гарантируется:

std:::pair<const int,int>& rx = reinterpret_cast<std:::pair<const int,int>&>(x);

Хотя кажется, что он грязный. Теперь я собираюсь мыть руки.

...