放松结构化绑定定制点查找规则 | P0961R1 |
结构化绑定的 lambda 捕获与存储类说明符 | P1091R3 |
允许到可访问成员的结构化绑定 | P0969R0 |
结构化绑定的Lambda捕获和存储类说明符
结构化绑定允许有[[maybe_unused]]属性、static和thread_local说明符。而且,现在可以在lambda中按值或按引用捕获它们。注意,绑定的位字段只能通过值捕获。
#include <iostream>
struct S{
int a: 1;
int b: 1;
int c;
};
static auto [A,B,C] = S{};
void f(){
[[maybe_unused]] thread_local auto [a,b,c] = S{0,0,1};
[[maybe_unused]]auto l = [=](){
return a + b + c;
};
std::cout << l() << std::endl;
[[maybe_unused]]auto m = [&](){
// error, can't capture bit-fields 'a' and 'b' by-reference
// return a + b + c;
return c;
};
}
int main()
{
f();
std::cout << A << std::endl;
return 0;
}
https://wandbox.org/nojs/gcc-head
https://wandbox.org/nojs/clang-head
放松结构化绑定自定义点查找规则
将类型分解为结构化绑定的一种方法是通过类似元组的 API。它由三个“函数”组成:std::tuple_element、std::tuple_size 和两个 get 选项:e.get<I>() 或 get<I>(e),其中第一个优先于第二个。也就是说,成员 get() 优先于非成员。想象一个类型有 get() 但它不适用于类似元组的 API,例如 std::shared_ptr::get()。这种类型无法分解,因为编译器会尝试使用成员 get() 并且它不起作用。现在,此规则已修复为仅当成员版本是模板且其第一个模板参数是非类型模板参数时才首选成员版本。
#include <iostream>
#include <memory>
struct X : private std::shared_ptr<int>{
std::string payload {"hello"};
};
// due to new rules, this function is used instead of std::shared_ptr<int>::get
template<int N>
std::string& get(X& x) {
if constexpr(N==0) return x.payload;
}
namespace std {
template<>
class tuple_size<X>
: public std::integral_constant<int, 1>
{};
template<>
class tuple_element<0, X> {
public:
using type = std::string;
};
}
void f(){
X x;
auto& [payload] = x;
std::cout << payload << std::endl;
}
int main()
{
f();
return 0;
}
允许结构化绑定到可访问的成员
此修复不仅允许对公共成员进行结构化绑定,还允许对结构化绑定声明上下文中可访问的成员进行结构化绑定。
#include <iostream>
struct A {
friend void f();
private:
int i;
};
void f() {
A a;
auto x = a.i; // OK
auto [y] = a; // Ill-formed until C++20, now OK
}
int main()
{
f();
return 0;
}
本文暂时没有评论,来添加一个吧(●'◡'●)