October 20, 2023

C++11新特性属性(Attribute)的简单解析

C++11加入的属性(Attribute)是给各种语言扩展(例如 GNUIBM 的语言扩展 __attribute__((...))微软 的语言扩展 __declspec() 等)提供了统一化的语法

属性可以运用在C++的几乎每个地方

C++目前引入的标准属性

语法

[[ 属性列表 ]]
[[ using 属性命名空间 : 属性列表 ]] // C++17开始

应用在函数上

[[deprecated("这个函数的实现不安全")]]
int foo();

应用在代码块上

#include <iostream>
int main() {
    if (1 > 0) [[likely]] {
        std::cout << "1>0";
    }
}

标准属性

noreturn

它表明了执行后不返回到调用者
使用了这个属性的函数有 exit(),abort()

#include <iostream>
#include <stdexcept>
[[noreturn]] void ExitProgram() {
    throw std::runtime_error("抛出错误"); // 抛出错误于是不会返回主函数
}
int main() {
    ExitProgram();
}

deprecated

[[deprecated(Message)]]

表示拥有该属性的实体被弃用,允许被使用,但是不鼓励使用
编译器通常会对其使用情况发出警告若指定了 字符串字面量(Message) ,则它通常被包含于警告中。

#include <stdexcept>

[[deprecated("会抛出异常")]]
void ExitProgram() {
    throw std::runtime_error("抛出错误");
}

int main() { ExitProgram(); }

编译输出

main.cpp:8:25: warning: ‘void ExitProgram()’ is deprecated: 会抛出异常 [-Wdeprecated-declarations]
    8 | int main() { ExitProgram(); }
      |              ~~~~~~~~~~~^~
main.cpp:4:35: note: declared here
    4 | [[deprecated("会抛出异常")]] void ExitProgram() {
      |                                   ^~~~~~~~~~~

多种使用方法

class/struct/union

class [[deprecated("这个类有新的实现可以代替")]] udp;

typedef/别名声明

[[deprecated("请使用标准的int32_t")]] typedef int32_t i32;
using i32 [[deprecated("请使用标准的int_32")]] = int32_t;

变量声明

[[deprecated]] int num;

class udp {
    [[deprecated("新版本将不再基于文件描述符")]] int fd_;
};

命名空间

namespace [[deprecated("以后将剥离net命名空间")]] net {
    class udp;
};

枚举/枚举项

enum [[deprecated("目前网络库并不完善")]] ip {
    v4,
    v6[[deprecated("目前对于ipv6的支持并不全面")]]
};

模板特化

template <typename type> struct MyStruct;
template <> struct [[deprecated("该类的实现有问题")]] MyStruct<int>;

nodiscard

可以增强代码的可读性和可维护性,从而提醒开发人员不要忽略返回的值
出现在函数声明、枚举声明或类声明中

[[nodiscard]] int foo() {
    return 10;
}

编译输出

main.cpp:7:17: warning: ignoring return value of ‘int foo()’, declared with attribute ‘nodiscard’ [-Wunused-result]
    7 | int main() { foo(); }
      |              ~~~^~
main.cpp:6:19: note: declared here
    6 | [[nodiscard]] int foo() { return 10; }
      |                   ^~~

struct

[[nodiscard]] struct MyStruct {
    int value;
};

void foo() {
    MyStruct myObject{42}; // 创建 MyStruct 对象
    // 使用对象的值
}

int main() {
    foo(); // 未使用 foo() 函数中 MyStruct 对象的返回值,编译器可能会发出警告
    return 0;
}

该文章并未完全写完,我将会在几天后完善该文章

About this Post

This post is written by JinHong Zeng, licensed under CC BY-NC 4.0.

#CPP