C++26 占位符变量改进
C++26 引入了占位符变量_
, 为编写代码提供了许多方便. 本文将做一个简单的介绍.
抑制未使用变量警告
如果代码中有未使用的局部变量, 编译器会发出警告. 有时候我们确实需要声明一个变量, 但是不使用它, 这时候可以使用占位符变量_
来抑制警告. 在此之前则需要使用[[maybe_unused]]
或者std::ignore
来抑制警告.
#include <tuple>
[[nodiscard]] int foo() { return 0; }
int main() {
// before C++26
[[maybe_unused]] int a = foo(); // OK
std::ignore = foo(); // OK
static_cast<void>(foo()); // Not recommended
// from C++26
auto _ = foo();
}
丢弃tuple
中的部分返回值
如果返回值是一个tuple
, 但是我们只关心其中的某几个值, 可以使用占位符变量_
来丢弃不关心的值. 下面的例子中有两个返回值被丢弃了.
#include <tuple>
[[nodiscard]] std::tuple<int, int, double> tuple() { return {0, 1, 1.0}; }
int main() {
auto [ret, _, _] = tuple();
return ret;
}
_
可被多次使用
_
可以被多次声明, 这不会产生命名冲突, 需要注意的是多次声明之后_
不能被使用. 另外不同文件中的_
是不同的, 不会产生冲突.
int multi() {
auto _ = 1; // OK
auto _ = 2.0; // OK, no confilict
auto _ = "string"; // OK, no confilict
auto [ret, _, _] = tuple(); // OK, no confilict
// return _; // Error, `_` has multi definition
return ret;
}
其他用法
- lambda函数中的
init captures
, 如[_ = 1]() { };
- 非静态成员变量, 除了匿名的
union
类型外, 可以使用_
作为成员变量名. 如struct S { int _; };
完整样例
#include <tuple>
[[nodiscard]] int foo() { return 0; }
[[nodiscard]] std::tuple<int, int, double> tuple() { return {0, 1, 1.0}; }
int multi() {
auto _ = 1; // OK
auto _ = 2.0; // OK, no confilict
auto _ = "string"; // OK, no confilict
auto [ret, _, _] = tuple(); // OK, no confilict
// return _; // Error, `_` has multi definition
return ret;
}
int main() {
// before C++26
[[maybe_unused]] int a = foo(); // OK
std::ignore = foo(); // OK
static_cast<void>(foo()); // Not recommended
// from C++26
auto _ = foo();
auto _ = multi();
auto [ret, _, _] = tuple();
return ret;
}
注意,本文是在gcc truck
版本上测试通过的, 源代码在Compiler Explorer上, 点击即可打开运行.