2016-10-13 3 views
-2

Как я могу конвертировать std::pair<const string,int> в std::pair<string,int> без фактической создания новой пары?Const Conversion in std :: pair

Я попытался с помощью static_cast, как показано ниже:

static_cast<std::pair<const string, int>>(curr->valPair) 

curr-> valPair - возвращается std::pair<string,int>

Но она возвращается ошибка:

invalid initialization of non-const reference of type ‘std::pair<const std::basic_string<char>, int>&’ from an rvalue of type ‘std::pair<const std::basic_string<char>, int>’ 

[Edit: Короче вопрос как конвертировать std::pair<string,int> в std::pair<const string,int>]

Edit2:

Добавление небольшой кусочек кода, чтобы воспроизвести проблему

#include<iostream> 

using namespace std; 

class A 
{ 
    std::pair<int,int> valPair; 

    public: 
     std::pair<const int,int> & getPairByReference(); 
}; 

std::pair<const int,int> & A::getPairByReference() 
{ 
    return valPair; 
} 

int main() 
{ 
    A a; 
    a.getPairByReference(); 
    return 0; 
} 

я получаю ниже ошибки при компиляции:

try-5.cpp: In member function ‘std::pair<const int, int>& A::getPairByReference()’: 
try-5.cpp:15:12: error: invalid initialization of reference of type ‘std::pair<const int, int>&’ from expression of type ‘std::pair<int, int>’ 
+0

Можете ли вы объяснить, что случилось с вопросом? –

+0

На ваш вопрос не хватает контекста. Что такое curr, какова ссылка, которую упоминает сообщение об ошибке, и т. Д. Просьба представить минимальный, полный и проверяемый пример. http://stackoverflow.com/help/mcve. – mars

+0

@ Eichhörnchen - Я упомянул в вопросах, чтоcurr-> valPair is std :: pair

ответ

4

То, что вы пытаетесь сделать, это возможно только если после преобразования не требуется curr->valPair, то

std::pair<const string, int> newPair(std::move(curr->valPair)); 

перемещает std::pair<string, int> через конструкцию перемещения в std::pair<const string, int>.

Если значение curr->valPair должно быть сохранено, это не означает, что для преобразования типов требуется построение экземпляра типа назначения. Копирование строки можно избежать только путем перемещения.

Однако вы, вероятно, захотите сделать это преобразование, потому что вам нужен конкретный тип назначения с const string. Было бы лучше, если бы вы объяснили предполагаемое использование. Вероятно, проблема там.

После вопроса редактирования:

Вы не можете иметь ссылку типа std::pair<const int, int>&, указывающий на объект типа std::pair<int, int>. Это два совершенно независимых типа. Прежде чем вы сможете получить ссылку на такой тип, вам нужно построить объект типа std::pair<const int, int>.

Дополнительное примечание:

reinterpret_cast может быть действительным здесь (и приведет исключения мои высказывания выше), я не уверен, here is a discussion on the topic. См. Ответ @ StoryTeller.

+0

Я добавил пример кода, и я пытаюсь сделать что-то подобное. Я хочу вернуть ссылку valPair, как в коде. –

+0

@MayankJain Увеличенный мой ответ, я думаю, что вы столкнулись с проблемой [XY] (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) здесь. – user4407569

+0

В этом случае я изменю свой член класса. Большое спасибо. –

0

Несмотря на то, что std::string неявно конвертируется в const std::string, два типа пары различаются. Что вы ищете, это reinterpret_cast по std::pair<const std::string, int>&.

Выполнение reinterpret_cast означает, что вы подавляете почти всю диагностику компилятора, полностью обходя систему типов. В этом случае он может быть довольно мягким, но в целом вы лучше знаете, что именно вы делаете.

0

Я думаю, что получил то, что вы хотите.У вас есть член класса, который является pair<T, U> (не const), но хочет, чтобы пользователь этого класса ссылался на этот элемент, но также должен запретить пользователю изменять первый элемент. Я прав?

Вместо того, чтобы ссылки на пару с различным сопзЬ-классификатором для аргументов шаблона (pair<const T, U>& из pair<T, U>) может быть, вы можете использовать пару ссылок с различным сопзЬ-классификатором (pair<const T&, U&> вместо pair<const T, U>&).

Построение пары ссылок намного дешевле, чем копирование элементов. И копия, вероятно, не имеет смысла, если вы хотите, чтобы пользователь изменил второй параметр в исходном экземпляре.

Чтобы построить пару ссылок:

std::pair<const string&, int&> A::getPairByReference() 
{ 
    return {valPair.first, valPair.second}; 
} 
Смежные вопросы