这是否是C ++中的缺陷std :: get <t>(const std :: pair <const t,=“”u =“”>&amp;)由于const T而无法编译?

时间:2018-01-29 20:20:01

标签: c++ c++14

作为标题。

使用std::get<T>(pair)时发生此编译错误,其中第一个成员是const,来自std::mapstd::unordered_map的迭代器。

要测试编译错误,请注释掉&#34; notstd&#34;过载get

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

现有的答案让我相信它应该是一个缺陷报告,应该将相应的std::get重载添加到标准库中,并且应该扩展应用于临时常量引用的自动生命周期扩展涵盖此类案件。

我还研究了它是否与布局的专业化有关(问题14272141,链接如下)。但是,我的代码片段仅要求对两个成员之一的const引用;即使布局专门化,对任一成员的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;
}

具有高度相关性的问题:

(谦卑通知:尽管我声称这看起来像是一个缺陷报告,但我脑子里可能有一些缺失的知识,所以请让我知道。从下面的rioki的回答中,我可以看到当前设计允许区分std::pair<const int, int>中的两个参数,而我的提议将失败。)

我对现状的描述:

  • 恼人的不一致,因为当两个习语(typed-get,并且始终使用基于范围的for来自vector<pair>unordered_map<pair>)一起使用时出现问题,并且解释了这种不兼容性并不适合任何人,包括初学者和有经验的程序员。
  • 存在一个或多个令人满意的解决方法,如rioki的回答所述。
  • 可能没有那么多的缺陷报告(因为现有代码可能依赖于区分const intint的能力),或者在不破坏现有代码的情况下无法改进

2 个答案:

答案 0 :(得分:12)

  

由于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通过pairtuple Tspecified as

  

需要:类型Types...pair中只出现一次。否则,该程序就是格式不正确。

如果我们将tuple视为int的特例,{const int, bool}int中不会出现一次,那么该程序应该是格式错误的。

换句话说:您要求该对中的int,但那里没有const int。那里有bool,而且 import java.util.Scanner; public class LetterGrade { public static void main(String[] args) { double Grade; Scanner scanner = new Scanner(System.in); System.out.print("Insert first grade: "); Grade = scanner.next(); System.out.print("Insert second grade: "); Grade = Grade + scanner.next(); System.out.print("Insert third gade: "); Grade = Grade + scanner.next(); System.out.print(Grade); } }

答案 1 :(得分:0)

你想要达到什么目标?

我会质疑首先在对中使用const值类型的智慧。你认为你用那个const实现了什么?

如果你假装没有std :: pair,你会实现这样的:

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);

然后,我再也没有真正理解为什么打字得到甚至是一件事。因为这样更清楚

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

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

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

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