-1

How can I convert std::pair<const string,int> to std::pair<string,int> without actually making a new pair?

I tried using static_cast as below:

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

curr->valPair - is returning std::pair<string,int>

But it is returning error:

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: In short the question is how to convert std::pair<string,int> to std::pair<const string,int>]

Edit2:

Adding a small piece of code to reproduce the issue

#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;
}

I am getting below error while compiling it:

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>’
T.C.
  • 133,968
  • 17
  • 288
  • 421
Mayank Jain
  • 2,504
  • 9
  • 33
  • 52

3 Answers3

4

What you are trying to do is only possible if curr->valPair is not needed anymore after the conversion, then

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

moves the std::pair<string, int> through move construction into a std::pair<const string, int>.

If the value of curr->valPair must be retained there is no way of doing this because type conversion requires construction of an instance of the destination type. Copying the string can only be avoided through a move.

However you probably want to do this conversion because you need the specific destination type with const string somewhere. It would be better if you explained the intended usage. The problem likely lies there.

After question edit:

You cannot have a reference of type std::pair<const int, int>& pointing to an object of type std::pair<int, int>. These are two completely independent types. You need to construct an object of type std::pair<const int, int> first before you can have a reference to such a type.

Additional note:

reinterpret_cast may be valid here (and would result in exceptions to my statements above), I am not sure, here is a discussion on the topic. See @StoryTeller's answer.

  • I have added a sample code and I am trying to do something similar. I want to return reference of valPair as in code in question. – Mayank Jain Oct 13 '16 at 19:36
  • @MayankJain Extended my answer, I think you are running into an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) here. –  Oct 13 '16 at 19:41
  • In this case I will change my member of class itself. Thanks a lot. – Mayank Jain Oct 13 '16 at 19:42
1

I think I got what you want. You have a class member that is a pair<T, U> (non-const), but want the user of the class to reference that member, but also want to disallow the user to modify the first item. Am I right?

Instead of making reference to a pair with different const-qualifier for the template arguments (pair<const T, U>& from pair<T, U>) maybe you can use a pair of references with different const-qualifier (pair<const T&, U&> instead of pair<const T, U>&).

Constructing a pair of references is much cheaper than copying the members. And the copy probably wouldn't make sense if you do want the user to modify the second parameter on the original instance.

To construct the pair of references:

std::pair<const string&, int&> A::getPairByReference()
{
    return {valPair.first, valPair.second};
}
André Sassi
  • 1,076
  • 10
  • 15
0

Even though a std::string is implicitly convertible to const std::string, the two pair types are distinct. What you seek to do is a reinterpret_cast to std::pair<const std::string, int>&.

Doing a reinterpret_cast means you suppress almost all compiler diagnostics by going completely around the type system. In this case it may be fairly benign, but in general you better know exactly what you are doing.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458