过年之无用知识研究:std::is_assignable means?

 std::pair的默认operator=被delete掉了,取而代之的是两个enable_if版本。

为什么这么设计,我的理解是pair作为左值时,里面的first如果是const,那么就不允许了。比如,在std::map里,已经保存的元素的key值是不能被修改的,这一点会在编译时报出错误。比如

注意,下面的代码会修改key值,编译时出现错误:
两个enable_if版本推导失败,最后落到了:pair& operator=(const volatile pair&) = delete;
这个版本,但这个版本又被删除了。所以出现了编译错误。{std::map<int, int> m;//初始化auto it = m.begin();*it = std::make_pair(1, 1); //问题就出在这里
}就会提示:
error C2679: 二进制“=”: 没有找到接受“std::pair<int,int>”类型的右操作数的运算符(或没有可接受的转换)
1>d:\devtools\vs2017\vc\tools\msvc\14.16.27023\include\utility(276): note: 可能是“std::pair<const _Kty,_Ty> &std::pair<const _Kty,_Ty>::operator =(volatile const std::pair<const _Kty,_Ty> &)”
1>        with
1>        [
1>            _Kty=int,
1>            _Ty=int
1>        ]
1>c:\work\hchx\ceripipe\codestudy\consoleapplication2\consoleapplication1\consoleapplication1.cpp(2114): note: 尝试匹配参数列表“(std::pair<const _Kty,_Ty>, std::pair<int,int>)”时
1>        with
1>        [
1>            _Kty=int,
1>            _Ty=int
1>        ]

代码:
std::pair<int, int> data0 = std::make_pair(1, 2);
std::pair<const int, int> data1 = std::make_pair(3, 4);
data0 = data1;堆栈中可以看到推导结果:
1.exe!std::pair<int,int>::operator=<int const ,int,0>
(const std::pair<int const ,int> & _Right={...}) 行 288	C++推导出的符号,
_Ty1和_Other1类型是:const int
_Ty2和_Other2类型是:int查看pair的operator=的enable_if不分,
is_assignable<_Ty1&, const _Other1&>怎么算,替换下来就是:
is_assignable<const int&, const const int&>
看到const const int&,居然有两个const,能行吗?考虑到is_asignable的实现,也就是相当于,
{using T = decltype(declval<int&>() = declval<const const int&>());int b = 0;T a = b;std::ignore = a;
}
vs2015下编译成功。神奇。
而is_assignable<_Ty1&, const _Other1&>就是:is_assignable<int&, const int&>
{using T = decltype(declval<int&>() = declval<const int&>());int b = 0;T a = b;std::ignore = a;
}
vs2015下也能编译成功。std::cout << boost::typeindex::type_id_with_cvr<const const int&>().pretty_name() << std::endl;
打印结果是:int const & __ptr64所以,enable_if_t<conjunction_v<is_assignable<_Ty1&, const _Other1&>,is_assignable<_Ty2&, const _Other2&>>, int>推导成功,
相当于:enable_if_t<conjunction_v<true,true>, int> 
-> enable_if_t<true, int> 
-> int所以才走到了下面的operator=的版本。结合源码:pair& operator=(const volatile pair&) = delete; //默认的版本已被删除template<class _Other1 = _Ty1, //_Ty1:const int, _Other1: const intclass _Other2 = _Ty2, //_Ty2:int      , _Other2: intenable_if_t<conjunction_v<is_assignable<const int&, const const int&>,is_assignable<int&      , const int&>>, int> = 0>pair& operator=(const pair<const int, int>& _Right)_NOEXCEPT_COND(is_nothrow_assignable_v<_Ty1&, const _Other1&>&& is_nothrow_assignable_v<_Ty2&, const _Other2&>)	// strengthened{first = _Right.first;second = _Right.second;return (*this);}

How to interpret declval<_Dest>() = declval<_Src>() in is_assignable

I am trying to figure out how to interpret declval<_Dest>() = declval<_Src>() in the implementation of is_assignable.

declval turns a type into a reference. Given that, I translate the expression into one of the following four possibilities:

  1. _Dest&& = _Src&&
  2. _Dest&& = _Src&
  3. _Dest& = _Src&&
  4. _Dest& = _Src&

I then created two helper functions.

template <typename T> T rvalue();
template <typename T> T& lvalue();

My understanding is the four expressions can be realized by using the template functions.

  1. _Dest&& = _Src&& -----> rvalue<_Dest>() = rvalue<_Src>()

Same goes for the other three.

Then I simulated decltype(declval<_Dest>() = declval<_Src>(), ..) by compiling the templated function version of each of the possibilities for three pairs of concrete types.

  • _Dest=int, _Src=int. Compiler accepts #3 and #4. is_assignable returned true for #3 and #4. They agreed.
  • _Dest=int, _Src=double. Same result as
  • _Dest=double, _Src=int. For this one, the compiler and is_assignable didn't agree. Compiler again does not like assigning to rvalues. However, is_assignable returns true for all four possibilities.

My questions are

  • Did I interpret declval<_Dest>() = declval<_Src>() correctly? In order words, does this really translate into the four possibilities. If yes, can each one be mapped to a templated function expression?
  • Why the compiler and is_assignable disagree on the _Dest=double, _Src=int case?

Thanks.

  • c++
  • c++11

Share

Improve this question

Follow

edited Dec 6, 2013 at 5:34

ildjarn

63k99 gold badges131131 silver badges216216 bronze badges

asked Dec 6, 2013 at 2:35

Candy Chiu

6,67999 gold badges5151 silver badges7070 bronze badges

  • 1

    Which compiler is "the" compiler? At least one compiler appears to work precisely as you expect.

    – Igor Tandetnik

     Commented Dec 6, 2013 at 3:18 
  • The compiler is VC++2013

    – Candy Chiu

     Commented Dec 6, 2013 at 13:21 
https://ideone.com/QdRjZB#include <iostream>
#include <type_traits>
using namespace std;template <typename T>
T rvalue() { return T(); }template <typename T>
T& lvalue() { static T t; return t; }int main() {cout << is_assignable<double, int>::value;cout << is_assignable<double, int&>::value;cout << is_assignable<double&, int>::value;cout << is_assignable<double&, int&>::value;// rvalue<double>() = rvalue<int>(); // Doesn't compile// rvalue<double>() = lvalue<int>(); // Doesn't compilelvalue<double>() = rvalue<int>(); // OKlvalue<double>() = lvalue<int>(); // OKreturn 0;
}

一个回答:

std::declval is actually specified to be (C++11 §20.2.4 [declval] p1):

template <class T>
typename add_rvalue_reference<T>::type declval() noexcept;

The result of the reference collapsing rules (§8.3.2 [dcl.ref] p6) is that declval returns an lvalue reference when T is an lvalue reference type, and an rvalue reference otherwise. So yes, your interpretation is correct.

If your compiler thinks that double&& is assignable from any type, then it has a bug. §5.17 [expr.ass] p1 states:

The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.

[emphasis mine].

Many programmers choose to emulate this behavior - assingment only to lvalues - with their own types by declaring the assignment operators with an lvalue reference qualifier:

class foo {foo& operator = (const foo&) & = default;foo& operator = (foo&&) & = default;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/68408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【愚公系列】《循序渐进Vue.js 3.x前端开发实践》030-自定义组件的插槽Mixin

标题详情作者简介愚公搬代码头衔华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xff0c;阿里云签约作者&#xff0c;腾讯云优秀博主&…

基于SpringBoot电脑组装系统平台系统功能实现六

一、前言介绍&#xff1a; 1.1 项目摘要 随着科技的进步&#xff0c;计算机硬件技术日新月异&#xff0c;包括处理器&#xff08;CPU&#xff09;、主板、内存、显卡等关键部件的性能不断提升&#xff0c;为电脑组装提供了更多的选择和可能性。不同的硬件组合可以构建出不同类…

网络工程师 (5)系统可靠性

前言 系统可靠性是指系统在规定的条件和规定的时间内&#xff0c;完成规定功能的能力。这种能力不仅涵盖了系统本身的稳定性和耐久性&#xff0c;还涉及了系统在面对各种内外部干扰和故障时的恢复能力和容错性。系统可靠性是评价一个系统性能优劣的关键指标之一&#xff0c;对于…

【2024年华为OD机试】(C卷,200分)- 推荐多样性 (JavaScriptJava PythonC/C++)

一、问题描述 问题描述 我们需要从多个已排序的列表中选取元素&#xff0c;以填充多个窗口。每个窗口需要展示一定数量的元素&#xff0c;且元素的选择需要遵循特定的穿插策略。具体来说&#xff0c;我们需要&#xff1a; 从第一个列表中为每个窗口选择一个元素&#xff0c;…

损失函数 Loss Function

分类问题和回归问题常使用的损失函数如下&#xff1a; 分类问题 交叉熵损失函数&#xff08;Cross-Entropy Loss&#xff09;&#xff1a;用于衡量两个概率分布之间的差异&#xff0c;在多分类问题中广泛应用。 ce_loss nn.CrossEntropyLoss() 回归问题 均方误差损失函数&…

Chameleon(变色龙) 跨平台编译C文件,并一次性生成多个平台的可执行文件

地址:https://github.com/MartinxMax/Chameleon Chameleon 跨平台编译C文件&#xff0c;并一次性生成多个平台的可执行文件。可以通过编译Chameleon自带的.C文件反向Shell生成不同平台攻击载荷。 登录 & 代理设置 按照以下步骤设置 Docker 的代理&#xff1a; 创建配置目…

DFFormer实战:使用DFFormer实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

几种K8s运维管理平台对比说明

目录 深入体验**结论**对比分析表格**1. 功能对比****2. 用户界面****3. 多租户支持****4. DevOps支持** 细对比分析1. **Kuboard**2. **xkube**3. **KubeSphere**4. **Dashboard****对比总结** 深入体验 KuboardxkubeKubeSphereDashboard 结论 如果您需要一个功能全面且适合…

DeepSeek API 的获取与对话示例

代码文件下载&#xff1a;Code 在线链接&#xff1a;Kaggle | Colab 文章目录 注册并获取API环境依赖设置 API单轮对话多轮对话流式输出更换模型 注册并获取API 访问 https://platform.deepseek.com/sign_in 进行注册并登录&#xff1a; 新用户注册后将赠送 10 块钱余额&#…

基于STM32的循迹小车设计与实现

1 系统方案设计 根据系统设计功能&#xff0c;展开基于STM32的循迹小车设计&#xff0c;整体设计框图如图2.1所示。系统采用STM32单片机作为控制器,通过L298驱动器控制两个直流电机实现对小车的运动控制&#xff0c;两路红外模块实现黑线的检测&#xff0c;HC-SR04超声波模块实…

Docker/K8S

文章目录 项目地址一、Docker1.1 创建一个Node服务image1.2 volume1.3 网络1.4 docker compose 二、K8S2.1 集群组成2.2 Pod1. 如何使用Pod(1) 运行一个pod(2) 运行多个pod 项目地址 教程作者&#xff1a;教程地址&#xff1a; https://www.bilibili.com/video/BV1Zn4y1X7AZ?…

算法每日双题精讲 —— 二分查找(寻找旋转排序数组中的最小值,点名)

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 别再犹豫了&#xff01;快来订阅我们的算法每日双题精讲专栏&#xff0c;一起踏上算法学习的精彩之旅吧&#x1f4aa; 在算法的…

【踩坑日常,已解决】彻底修改IDEA项目的JDK版本,8改为17

三处修改彻底解决IDEA中JDK版本不对问题&#xff08;8改为17&#xff09; 文章目录 三处修改彻底解决IDEA中JDK版本不对问题&#xff08;8改为17&#xff09;第一处第二处第三处 第一处 setting -> Build, Execution, Deployment -> Java Compiler -> Target bytecod…

redis的分片集群模式

redis的分片集群模式 1 主从哨兵集群的问题和分片集群特点 主从哨兵集群可应对高并发写和高可用性&#xff0c;但是还有2个问题没有解决&#xff1a; &#xff08;1&#xff09;海量数据存储 &#xff08;2&#xff09;高并发写的问题 使用分片集群可解决&#xff0c;分片集群…

Nuxt:利用public-ip这个npm包来获取公网IP

目录 一、安装public-ip包1.在Vue组件中使用2.在Nuxt.js插件中使用public-ip 一、安装public-ip包 npm install public-ip1.在Vue组件中使用 你可以在Nuxt.js的任意组件或者插件中使用public-ip来获取公网IP。下面是在一个Vue组件中如何使用它的例子&#xff1a; <template…

搭建Spring Boot开发环境

JDK&#xff08;1.8及以上版本&#xff09; Apache Maven 3.6.0 修改settings.xml 设置本地仓库位置 <localRepository>D:/repository</localRepository> 设置远程仓库镜像 <mirror><id>alimaven</id><name>aliyun maven</name&…

智慧校园在职业学校的实施与展望

随着信息技术的发展&#xff0c;智慧校园的概念逐渐走进人们的视野。智慧校园不仅是一个技术层面的概念&#xff0c;更是教育理念的一次革新。对于职业教育而言&#xff0c;智慧校园的应用更是具有重要意义。通过引入物联网、大数据等先进技术&#xff0c;可以实现教学资源的高…

Excel中LOOKUP函数的使用

文章目录 VLOOKUP&#xff08;垂直查找&#xff09;&#xff1a;HLOOKUP&#xff08;水平查找&#xff09;&#xff1a;LOOKUP&#xff08;基础查找&#xff09;&#xff1a;XLOOKUP&#xff08;高级查找&#xff0c;较新版本Excel提供&#xff09;&#xff1a; 在Excel中&…

React第二十六章(createPortal)

createPortal 注意这是一个API&#xff0c;不是组件&#xff0c;他的作用是&#xff1a;将一个组件渲染到DOM的任意位置&#xff0c;跟Vue的Teleport组件类似。 用法 import { createPortal } from react-dom;const App () > {return createPortal(<div>小满zs<…

k8s 蓝绿发布、滚动发布、灰度发布

在Kubernetes&#xff08;k8s&#xff09;中&#xff0c;蓝绿发布、滚动发布、灰度发布&#xff08;金丝雀发布&#xff09;是三种常见的应用部署和更新策略。下面将分别对这几种发布方式进行说明&#xff0c;并给出相应的例子。 蓝绿发布 蓝绿发布是一种无缝切换版本的部署策…