C++17特性:新标准属性

C++17新增了3个属性: [[fallthrough]][[nodiscard]] 和 [[maybe_unused]]

看一个快速的例子:

  1. #include <cassert>

  2. // 如果 foo() 返回值被忽略不用编译器会警告

  3. [[nodiscard]] int foo();

  4. int main() {

  5. int a {1};

  6. switch (a) {

  7. // 指明case 1会掉下去

  8. case 1: [[fallthrough]]

  9. case 2:

  10. // 指明b 可能没用上,例如release build中

  11. [[maybe_unused]] int b = foo();

  12. assert(b > 0);

  13. break;

  14. }

  15. }

[[fallthrough]]

C++17之前的标准下,有如下代码:

  1. switch (device.status())

  2. {

  3. case sleep:

  4. device.wake();

  5. // fall thru

  6. case ready:

  7. device.run();

  8. break;

  9. case bad:

  10. handle_error();

  11. break;

  12. }

在C++17时可以这样写:

  1. switch (device.status())

  2. {

  3. case sleep:

  4. device.wake();

  5. [[fallthrough]];

  6. case ready:

  7. device.run();

  8. break;

  9. case bad:

  10. handle_error();

  11. break;

  12. }

区别就是新增的 [[fallthrough]]属性。如果这里不写 [[fallthrough]],编译也是能通过的,但会报诸如 warning: case statement without break之类的警告。C++中 switch-case默认是会继续往下走,有的时候程序员可能因为粗心会漏写 break,就会导致非预期的运行逻辑,有的语言比如Go则默认会跳出当前 case,C++17中新增 [[fallthrough]]属性可以多一次机会提醒程序员仔细思考这里正常逻辑应该是怎样的。

[[nodiscard]]

C++17之前的标准下,有如下代码:

  1. struct SomeInts

  2. {

  3. bool empty();

  4. void push_back(int);

  5. //etc

  6. };

  7. void random_fill(SomeInts & container,

  8. int min, int max, int count)

  9. {

  10. container.empty(); // empty it first

  11. for (int num : gen_rand(min, max, count))

  12. container.push_back(num);

  13. }

在C++17时可以这样写:

  1. struct SomeInts

  2. {

  3. [[nodiscard]] bool empty();

  4. void push_back(int);

  5. //etc

  6. };

  7. void random_fill(SomeInts & container,

  8. int min, int max, int count)

  9. {

  10. container.empty(); // empty it first

  11. for (int num : gen_rand(min, max, count))

  12. container.push_back(num);

  13. }

加上 [[nodiscard]]后,编译器发现 empty()函数被调用时并没有使用它的返回值,则会报一个诸如 warning: ignoring return value of 'bool empty()'的警告。

除了可以用在函数上,也可以用在类或结构体上,作用是该类或结构体被作为返回值类型时,如果不使用该返回值,则编译器警告。例如:

  1. struct [[nodiscard]] MyError {

  2. std::string message;

  3. int code;

  4. };

  5. MyError divide(int a, int b) {

  6. if (b == 0) {

  7. return {"Division by zero", -1};

  8. }

  9. std::cout << (a / b) << '\n';

  10. return {};

  11. }

  12. divide(1, 2);

报警告 warning: ignoring return value of function declared with 'nodiscard' attribute

建议要谨慎考虑是否真的需要使用 [[nodiscard]]属性,如果确实任何情况下都没理由可以忽略掉返回值,则可以使用。

[[maybe_unused]]

有代码如下:

  1. bool res = step1();

  2. step2();

  3. etc();

编译时可能会报警告说 res变量定义了却没有使用诸如此类的话。C++17引入了 [[maybe_unused]]属性,可以修改如下:

  1. [[maybe_unused]] bool res = step1();

  2. step2();

  3. etc();

这样编译器就不会再对 res变量没有被使用而报警告了。

除了可以修饰变量,此属性也可用于修饰函数,例如:

  1. [[maybe_unused]] void f()

  2. {

  3. /*...*/

  4. }

  5. int main()

  6. {

  7. }

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值