【问题标题】:Const Conversion in std::pairstd::pair 中的常量转换
【发布时间】:2016-10-13 19:16:22
【问题描述】:

如何将std::pair<const string,int> 转换为std::pair<string,int> 而无需实际制作一对?

我尝试如下使用 static_cast:

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

curr->valPair - 返回std::pair&lt;string,int&gt;

但它返回错误:

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>’

[编辑:简而言之,问题是如何将std::pair&lt;string,int&gt; 转换为std::pair&lt;const string,int&gt;]

编辑2:

添加一小段代码来重现问题

#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>’

【问题讨论】:

  • 你能解释一下这个问题有什么问题吗?
  • 您的问题缺少很多上下文。什么是 curr,错误消息提到的参考是什么等。请提供一个最小、完整和可验证的示例。 stackoverflow.com/help/mcve.
  • @Eichhörnchen - 我在问题中提到curr->valPair 是 std::pair
  • 如果你把一个 X 转换成一个 Y,你就创造了一个新的 Y。你想做什么,不想做什么?
  • 对不起,如果问题令人困惑..我将添加一个小测试代码。

标签: c++ std-pair


【解决方案1】:

只有在转换后不再需要 curr-&gt;valPair 时,您才可能执行此操作,然后

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

通过移动构造将std::pair&lt;string, int&gt;移动到std::pair&lt;const string, int&gt;

如果必须保留curr-&gt;valPair 的值,则无法执行此操作,因为类型转换需要构造目标类型的实例。复制字符串只能通过移动来避免。

但是您可能希望进行此转换,因为您需要在某处带有const string 的特定目标类型。如果您解释预期用途会更好。问题可能就在那里。

问题编辑后:

您不能将 std::pair&lt;const int, int&gt;&amp; 类型的引用指向 std::pair&lt;int, int&gt; 类型的对象。这是两个完全独立的类型。您需要先构造一个std::pair&lt;const int, int&gt; 类型的对象,然后才能引用这种类型。

补充说明:

reinterpret_cast 可能在这里有效(并且会导致我上面的陈述出现例外),我不确定here is a discussion on the topic。请参阅@StoryTeller 的回答。

【讨论】:

  • 我添加了一个示例代码,我正在尝试做类似的事情。我想在相关代码中返回 valPair 的引用。
  • @MayankJain 扩展了我的答案,我认为您在这里遇到了XY problem
  • 在这种情况下,我将更改班级本身的成员。非常感谢。
【解决方案2】:

我想我得到了你想要的。您有一个类成员是 pair&lt;T, U&gt;(非常量),但希望该类的用户引用该成员,但也希望禁止用户修改第一项。我说的对吗?

您可以使用具有不同 const 限定符的一对引用(pair&lt;const T&amp;, U&amp;&gt; 而不是 pair&lt;const T, U&gt;&amp; )。

构造一对引用比复制成员便宜得多。如果您确实希望用户修改原始实例上的第二个参数,则副本可能没有意义。

构造引用对:

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

【讨论】:

    【解决方案3】:

    即使 std::string 可以隐式转换为 const std::string,这两种对类型是不同的。 你想要做的是reinterpret_caststd::pair&lt;const std::string, int&gt;&amp;

    执行reinterpret_cast 意味着您通过完全绕过类型系统来抑制几乎所有编译器诊断。在这种情况下,它可能是相当良性的,但总的来说,您最好确切地知道自己在做什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-14
      • 2015-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-27
      • 2021-09-15
      • 1970-01-01
      相关资源
      最近更新 更多