比较两个map::iterators:为什么它需要std::pair的复制构造函数?

2024-04-21

下面非常简单的代码在 C++98 中编译和链接时不会发出警告,但在 C++11 模式中会出现难以理解的编译错误。

#include <map>

struct A {
    A(A& ); // <-- const missing
};

int main() {
    std::map<int, A> m;
    return m.begin() == m.end(); // line 9
}

错误与-std=c++11是,gcc 版本 4.9.0 20140302(实验)(GCC):




ali@X230:~/tmp$ ~/gcc/install/bin/g++ -std=c++11 cctor.cpp 
In file included from /home/ali/gcc/install/include/c++/4.9.0/bits/stl_algobase.h:64:0,
                 from /home/ali/gcc/install/include/c++/4.9.0/bits/stl_tree.h:61,
                 from /home/ali/gcc/install/include/c++/4.9.0/map:60,
                 from cctor.cpp:1:
/home/ali/gcc/install/include/c++/4.9.0/bits/stl_pair.h: In instantiation of ‘struct std::pair’:
cctor.cpp:9:31:   required from here
/home/ali/gcc/install/include/c++/4.9.0/bits/stl_pair.h:127:17: error: ‘constexpr std::pair::pair(const std::pair&) [with _T1 = const int; _T2 = A]’ declared to take const reference, but implicit declaration would take non-const
       constexpr pair(const pair&) = default;
                 ^
  

使用 clang 版本 3.5(主干 202594)



ali@X230:~/tmp$ clang++ -Weverything -std=c++11 cctor.cpp 
In file included from cctor.cpp:1:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/map:60:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_tree.h:63:
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_algobase.h:65:
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_pair.h:119:17: error: the parameter for this explicitly-defaulted copy constructor is const, but
      a member or base requires it to be non-const
      constexpr pair(const pair&) = default;
                ^
cctor.cpp:9:22: note: in instantiation of template class 'std::pair' requested here
    return m.begin() == m.end(); // line 9
                     ^
1 error generated.
  

我一直在查看代码bits/stl_tree.h我不明白为什么它试图实例化std::pair.

为什么需要复制构造函数std::pair在 C++11 中?


Note: the above code was extracted from Equality operator (==) unsupported on map iterators for non-copyable maps https://stackoverflow.com/q/22341818/341970.


SOLUTION

这里有两个不幸的问题。

错误消息质量差:第 8 行应该已经给出编译错误,尽管错误消息只是抱怨第 9 行。在第 8 行得到错误将非常有帮助,并且理解真正的问题会容易得多。如果 gcc / clang 主干中仍然存在此问题,我可能会提交错误报告/功能请求。

另一个问题是什么ecatmur https://stackoverflow.com/a/22359998/341970写道。考虑以下代码:

struct A {
    A() = default;
    A(A& ); // <-- const missing
};

template<class T>
struct B {
    B() = default;
    B(const B& ) = default;
    T t;
};

int main() {
  B<A> b;  
}

它无法编译。即使任何地方都不需要复制构造函数,它仍然会被实例化,因为它默认是内联的,位于类的主体中;这会导致编译错误。这可以通过将复制构造函数移出类的主体来解决:

template<class T>
struct B {
    B() = default;
    B(const B& );
    T t;
};

template <class T>
B<T>::B(const B& ) = default;

那么一切就都OK了。很遗憾,std::pair有一个默认定义的内联复制构造函数。


的复制构造函数std::pair isn't needed在这种情况下,但因为它是在声明中默认定义的内联std::pair,它会随着实例化而自动实例化std::pair itself.

标准库可以提供复制构造函数的非内联默认定义:

template<class _T1, class _T2>
  struct pair
  {
// ...
    constexpr pair(const pair&);
// ...
  };
// ...
template<class _T1, class _T2>
constexpr pair<_T1, _T2>::pair(const pair&) = default;

然而,这不符合标准的严格规定(第 20.3.2 条),其中复制构造函数默认定义为内联:

  constexpr pair(const pair&) = default;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

比较两个map::iterators:为什么它需要std::pair的复制构造函数? 的相关文章

  • C# Socket.receive连续接收0字节且循环中不阻塞

    我正在尝试用 C 编写一个最简单的多线程 TCP 服务器 它接收来自多个客户端的数据 每次连接新客户端时 都会建立套接字连接 并将套接字作为参数传递给新类函数 之后运行 while 循环并接收数据 直到客户端连接为止 这里的问题是 sock
  • F1 2019 UDP解码

    我目前正在为 F1 方向盘开发自己的显示器 F1 2019 由codemasters提供 通过UDP发送数据 该数据存储在字节数组中 我在解码返回的数组时遇到一些问题 问题是我得到了很多信息 但我不知道如何处理它们 我将向您介绍我所尝试过的
  • C# 按下按钮时跳出循环

    我有一个简单的 C foreach 循环 如何在按下按钮时跳出循环 它不在backgroundWorker线程中 所以我不能使用backgroundWorker Cancellation Pending 在表单中创建一个布尔标志 将事件处理
  • 正确别名向量

    我无法在其他地方找到答案 所以我想我只需要问这个 我正在尝试获取向量 其中存储 int 指针 的别名 如下所示 void conversion Engine ENGINES The Engine class has a vector of
  • EWS 消息跟踪报告

    我一直在研究如何使用 EWS 从交换中获取消息跟踪报告 但似乎无法查明任何内容 我打算构建一个抓取日志文件的应用程序 但如果我可以通过 EWS 来完成它 那对我正在做的事情会更好 有任何想法吗 我终于能够为我的问题创建一个解决方案 我在 C
  • 如何设置属性选择器的值 Expression>

    我需要使用模式工厂的想法将 Person 类实体中的实体属性 Address 与 FactoryEntities 类中的表达式 linq 相关联 看看这就是我所拥有的并且我想要做的 Address address new Address a
  • 如何创建 .bat 文件来运行 C# 代码?

    我需要的是 我有一个 C 代码 我想构建它以便在桌面上创建一个 bat 文件 因此 当我从桌面运行这个 bat 文件时 它应该执行 C 代码 有没有办法在编译之前更改 c 项目的设置或属性 以便创建应运行此 c 代码的 bat 文件 将 C
  • 提高 ASP.NET/C# 编译速度的最佳方法是什么?

    更新 请将您的答案集中在硬件解决方案上 您使用什么硬件 工具 插件来提高 ASP NET 编译和首次执行速度 我们正在寻找固态硬盘来加快速度 但现在价格确实很高 我现在有两个 RAID 0 的 7200 rpm 硬盘 但我对性能不再满意 所
  • C# 中的异步方法如何工作?

    我在我的一些项目中使用异步方法 我喜欢它 因为它使我的应用程序更具可扩展性 但是 我想知道异步方法如何在后台真正工作 NET 或 Windows 如何知道调用已完成 根据我进行的异步调用的数量 我可以看到创建了新线程 但并不总是 为什么 此
  • 这个对象的内存会是什么样子?

    我想知道这个类 它的对象 的内存布局是什么样的 class MyClass string myString int myInt public MyClass string str int i myString str myInt i MyC
  • 如何存储生成的格式化 C 字符串

    这是一个新手问题 为了创建格式化的 C 字符串 我使用printf like int n 10 printf My number is i 10 但是 怎么样 int n 10 char msg My number is i 10 prin
  • 使用 .NET Core Razor Pages 将文件下载到浏览器

    使用 ASP NET Razor Pages 我尝试将文件下载到浏览器 在页面 html 中 使用这样的链接效果很好 href DownloadableFiles testB csv download newname gt Download
  • 枚举和枚举类之间的区别[重复]

    这个问题在这里已经有答案了 谁能解释一下两者之间的区别 enum Type1 type2 And enum class Type1 type2 我经常使用前者 可能太频繁而没有足够的封装 但我从未使用过第二个例子 Thanks enum A
  • 验证仅适用于数组的第一项

    给定这个模型代码 Required Display Name Name public string Name get set 以下查看代码有效 Html LabelFor model gt model Name Html TextBoxFo
  • 二叉树实现C++

    二叉树插入 include stdafx h include
  • 拦截C# HttpClient GetAsync

    我有一个 Web 项目 C MVC5 但没有 WebAPI 和一个简单的 HTTP REST 客户端 该客户端调用外部 REST 服务并获取 accessToken 等 我想检查所有 Get PostAsync 调用对 statusCode
  • 使用 Entity Framework Core 在运行时迁移

    我正在将 PHP Illuminate 应用程序移植到 ASP NET Core EF Core 其中一部分由类似 Wordpress 的安装过程组成 该过程要求提供数据库凭据 然后创建应用程序运行所需的表 本质上 我想在运行时运行某种迁移
  • C# 中的自定义按钮:如何删除悬停背景?

    我正在尝试使用 Visual Studio 2005 对我的表单 其 FormBorderStyle none 执行自定义按钮 我在链接到该按钮的 ImageList 中有我的 3 种状态按钮图像 this btnClose AutoSiz
  • 如何避免函数的多重定义(Linux、GCC/G++、Code::Blocks)

    我有一个代码块项目 它使用许多不同的文件 通常是由其他程序员编写的 目前我遇到的情况是 我有两个不同的子项目 其中包含以相同方式命名的函数 比方说 F int x 因此 F int x 是在两个不同位置的两个源文件中定义的 并且它们有两个不
  • Web 服务无法使用 GAC 中的类型创建类型错误

    遇到一个不寻常的问题时 我似乎喜欢做一些不常见的事情 我有一个复合控件 它检查给定的 Web 服务文件是否存在于我的应用程序的根目录中 如果不存在 它会在标记中创建带有必要指令的文件以进行滚动 如下所示 反过来 它被保存到输出中 完成此步骤

随机推荐