如何使我的 cmake 项目所需的某些 c++ 功能
How can I make certain c++ features required in my cmake project?
我正在为我的 c++14 项目编写CMakeLists.txt
。我希望其他用户能够构建我的项目,但他们的编译器可能不支持我正在使用的 c++14 功能。如果编译器不支持我的 c++14 代码,如何让 cmake 打印错误消息?
我找到了target_compile_features
命令,它似乎做正确的工作。但是,我不确定如何正确使用它...
这是对的吗?
CMakeLists.txt:
project(myproject VERSION 1.0.0
LANGUAGES CXX)
add_executable(myproject src/main.cpp)
target_compile_features(myproject PRIVATE cxx_auto_type)
...
因为我认为这是一个常见的问题,所以我会自己回答:
虽然一般用法是正确的,但如果你正在编写一个库,你需要调整 cmake 代码:
target_compile_features(myproject INTERFACE cxx_auto_type)
此外,您需要根据所使用的内容添加更多功能。这可以通过简单地列出它们来完成:
target_compile_features(myproject INTERFACE cxx_auto_type
cxx_static_assert
...)
CMAKE_CXX_KNOWN_FEATURES
可以在 cmake 文档中找到可能的值列表。但是,我发现简短的句子和指向 c++ 标准的链接并没有真正的帮助。因此,我将尝试描述每个选项包含哪些功能。
我想解释列表中的所有选项,但这需要很长时间来写......因此,我将从我认为有用或有趣的功能开始,但稍后会尝试添加更多功能。如果有人想添加我还没有来发布的内容,我也会不胜感激。
我将链接与原始文档相同的 c++ 标准文档,但我还将提供指向相应 cppreference 页面的链接,并在必要时提供一个小型编码示例。
cxx_auto_type
自动类型推断是在 C++11 和 N1984 中引入的。它允许用户在所有情况下编写auto
关键字,编译器可以自动推断结果类型。不必再给出实际类型。
例如:
auto i = 0; //it is clear that we want an int here
auto d = 1.45; //it is clear that we want a double here
...
cxx_binary_literals
二进制文字是在 C++14 中与 N3472 一起引入的。除了现有的十六进制文字之外,它们还允许以二进制形式写入值。
二进制文本在二进制值前面用0b
或0B
标记:
0B1000 == 8 //true
0b1001 == 9 //true
cxx_deleted_functions
删除的函数是在 C++11 中引入的 N2346。它们允许用户显式删除类中的某些运算符和成员函数。如果程序将访问任何已删除的函数,则代码将不会编译:
struct no_default_constructor {
no_default_constructor() = delete; //the default constructor is deleted
no_default_constructor(int value) : ...
...
};
因此,默认构造是不可能的,但另一个构造可能是。
no_default_constructor object = no_default_constructor(); //this will not compile
no_default_constructor object = no_default_constructor(2); //this will
cxx_explicit_conversions
在C++11 中使用 N2437 添加了显式转换。它们允许将类转换指定为显式,这意味着不可能进行隐式转换。
例如:
struct flag {
bool is_set;
explicit operator bool() const { return is_set; }
};
此类不能隐式转换为 bool,但仍可以显式转换:
void print_birthday_message(flag user_has_birthday) {
bool has_birthday = user_has_birthday; //this is not possible
bool has_birthday = bool(user_has_birthday); //but this is fine
...
}
cxx_final
最后一个关键字是在 c++11 中引入的 N2928、N3206 和 N3272。它允许类设计器防止用户覆盖虚拟函数或成员函数。
final
关键字必须写在虚函数的末尾,以防止额外的覆盖:
struct Base {
virtual void function();
};
struct A : Base {
void function() final; //overwrite Base::function and make it the final overwrite
};
struct B : A {
void function() override; //this is not possible, as function was already marked final inside A
};
final
关键字必须位于派生类名的末尾,以防止覆盖:
struct Base {};
struct A final : Base {}; //struct A is now final
struct B : A {}; //this is not possible, as A was already marked final
cxx_noexcept
noexcept 关键字是在 C++11 中引入的 N3050。它允许标记函数,运算符和构造函数。如果这些被标记为noexcept
,它们保证在调用它们时不会抛出任何异常。此外,"无例外性"可以通过noexcept(f)
函数进行测试。
cxx_raw_string_literals
原始字符串文字是在 C++11 中引入的 N2442。它们允许在不使用转义字符的情况下将任意字符写入字符串。
原始字符串采用R"delimiter(raw_characters)delimiter"
的形式,delimiter
是任意名称(遵循 c++ 命名标准)。一种常见的情况是使用它们直接在 c++ 中输入脚本代码。此外,编译器会忽略delimiter
,使用它来提示 IDE 脚本语言。
例如:
const char* code = R"chaiscript(
print("Hello World")
)chaiscript";
cxx_strong_enums
强类型枚举是在 C++11 中引入的 N2347。它们允许以某种方式设置枚举的类型,从而防止带有枚举的错误自动转换为其他类型的错误。
强类型枚举使用enum class name
语法。例如:
enum class colours {
cyan = 0,
red = 1,
green = 2,
};
这使得意外转换变得不可能:
int color_index = colours::green; //this conversion is not allowed!
int color_index = int(colours::green); //explicit casts are still okay
cxx_trailing_return_types
尾随返回类型是在 C++11 中引入的 N2541。它们允许在参数列表之后定义函数的返回类型:
auto greet() -> void {
std::cout << "Hello World!";
}
尾随返回类型在AAA(几乎总是自动)编程风格中很有用,在返回类型很复杂的情况下,或者在模板函数中可能取决于输入类型。
cxx_unicode_literals
Unicode 文字是在 C++11 中与 N2442 一起引入的。它们允许用户直接将 unicode 字符输入到 c++ 中,而无需使用 unicode 转义字符。(n
, ...还是要逃脱的。
它们采用的形式u8"(characters)"
.可以替换u8
以更改基础数据类型:
const char* utf8 = u8"(characters)";
const char16_t* utf16 = u"(characters)";
const char32_t* utf32 = U"(characters)";
cxx_user_literals
用户文字是在 C++11 中与 N2765 一起引入的。它们允许用户编写自定义类型快捷方式和自定义类型转换。
用户文本是用operator ""
定义的。例如,从度到弧度的转换可以这样写:
constexpr double operator "" _degrees(double value) {
return value*3.14/180.;
}
该值由以下方法获得:
double theta = 90_degrees; //==1.57
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 有没有可能有一个只有ADL才能找到的非好友功能
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 文件系统:复制功能的速度秘诀是什么
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 如何在Directwrite中获得给定字体的可用OpenType功能
- 对可变参数使用声明.如何选择正确的功能
- 询问在设计我的手臂模拟器功能表示格式1
- 功能原型的目的
- 这里在 Linux 中具有"CreatePipe"和"CreateProcessW"功能吗?