clang与gcc在C++23“推导this”特性上的行为分歧判定请求
clang与gcc在C++23“推导this”特性上的行为分歧判定请求
嘿,我来帮你梳理这个C++23里「推导this」(deducing this)的分歧问题~
首先,先明确你的代码意图:你想写一个隐式转换运算符模板,通过「推导this」来根据调用对象的值类别(左值/右值),让转换后的结果对应不同的值类别——左值foo转换后返回int&,右值foo转换后返回int(可以绑定到int&&)。
咱们先拆解代码里的关键部分:
conversion_type模板会根据O是否是左值引用,决定返回T&还是T- 转换运算符用了C++23的
this Self&&语法,这是「推导this」的写法,Self会根据调用对象的值类别自动推导:- 当调用对象是左值(比如
f),Self推导为foo&,所以conversion_type<int, Self>是int&,转换运算符实例化为operator int&(this foo& self),返回的self.asdf是int&,能正常绑定到int& fdsa - 当调用对象是右值(比如
std::move(f)),Self推导为foo,所以conversion_type<int, Self>是int,转换运算符实例化为operator int(this foo&& self),返回的std::forward<Self>(self).asdf是int纯右值(prvalue),按照C++规则,纯右值是可以绑定到右值引用int&& asdf的
- 当调用对象是左值(比如
现在来说gcc和clang的分歧:根据C++23标准的规则,这段代码是合法的,clang的行为是正确的,gcc的拒绝是错误的。
原因在于「推导this」的标准规则:对于this Self&&这种写法,Self的推导完全遵循转发引用的规则——左值实参推导为左值引用类型,右值实参推导为非引用类型。而转换后的纯右值int绑定到int&&是符合C++值类别绑定规则的,没有问题。
备注:内容来源于stack exchange,提问作者Chris Fretz
相关产品推荐
相关产品推荐

