这是 std::get ( const<T> std::p air<const T, U>& ) 由于 const T 而无法编译的C++缺陷吗?

Is this a defect in C++ that std::get<T> ( const std::pair<const T, U>& ) fail to compile due to const T?

本文关键字:const lt gt std 编译 缺陷 C++ air get 这是 由于      更新时间:2023-10-16

作为标题。

当使用std::get<T>(pair)时会发生此编译错误,其中对的第一个成员是常量,从迭代器中脱落std::mapstd::unordered_map

要测试编译错误,请注释掉get的"notstd"重载。

我已经在堆栈溢出上研究了这个问题,下面列出了三个最相关的问题。

现有的答案使我相信它应该是一个缺陷报告,相应的std::get过载应该添加到标准库中,并且应用于临时常量参考的自动寿命延长应该扩展到涵盖这种情况。

我还研究了它是否与布局的专业化有关(问题14272141,链接如下)。但是,我的代码片段只要求对两个成员之一的 const 引用;即使具有布局的专用化,对任一成员的常量引用也应仍然存在。

我知道,根据现有的答案,在const std::pair<T, U>&const std::pair<const T, U>&之间转换是不安全的。

namespace notstd
{
template <class T, class U>
const T& get(const std::pair<const T, U>& tu)
{
return tu.first;
}
}
int test(int value) 
{
using namespace notstd;
using namespace std;
const std::pair<const int, bool> one(value, false);
const auto two = get<int>(one);
const auto three = get<const int>(one);
return 0;
}

具有高度相关性的问题:

Bind const std::p air<T,>
  • & to value of std::p airconst& 安全吗?
  • std::is_assignable 和 std::p air

    这是std::get<T>(const std::pair<const T, U>& )由于const T而无法编译的C++缺陷吗?

    不。我非常希望这失败:

    std::pair<const int, bool> p(42, true);
    std::get<int>(p); // expected failure
    

    std::get<T>表示检索类型为T的元素。不是类型近似于T的元素,或衰减到T,或任何其他类似元素。std::get通过tuple的方式pair,其中指定为:

    要求:类型TTypes...中恰好出现一次。否则,程序格式不正确。

    如果我们将pair视为tuple的特例,int不会在{const int, bool}中恰好发生一次,因此程序应该是格式不正确的。

    换句话说:你要求那对中的int,但那里没有int。有const int,有bool.

你想实现什么?

我会质疑首先成对使用 const 值类型的明智性。你相信你用这个常量实现了什么?

如果你假装没有std::p air,你会实现它,如下所示:

struct my_pair
{ 
const int first;
const bool second;
}; 

但这对类型意味着什么。对于初学者来说,它是不可分配的。通常,pair的使用是在可复制的上下文中,因为您倾向于传递两个相关的值,而无需构建单独的类。如果在堆栈上使用一对,则不妨只使用两个变量。

但这里的根本问题有点不同。假设您有以下一对:

std::pair<const int, int> p;

如果你使用typed std::get,这有效:

auto first  = std::get<const int>(p);
auto second = std::get<int>(p);

话又说回来,我从来没有真正理解为什么键入的get甚至是一回事。因为这更清楚

auto first  = std::get<0>(p);
auto second = std::get<1>(p);

或者,在配对的情况下,只需使用旧的:

auto first  = p.first;
auto second = p.second;

所以我认为你的问题不是问题......