std::is_nothrow_convertible 用于编译期判断 From 到 To 的转换是否保证不抛异常;它要求所有可行转换路径中的函数均标记 noexcept,比 std::is_convertible 具备更强的异常安全约束。

std::is_nothrow_convertible 用来在编译期判断:从一个类型 From 到另一个类型 To 的隐式或显式转换,是否被保证为 noexcept —— 即该转换过程**绝不会抛出异常**。
它解决的核心问题
普通转换(比如构造、隐式类型转换、static_cast)可能抛异常(例如带 throw() 或 noexcept(false) 的构造函数),而某些场景(如 std::variant、std::optional 的赋值、容器的移动操作)要求“强异常安全”或“不抛异常”的行为。这时仅知道“能转换”(std::is_convertible)不够,还必须确认“转换过程本身不抛异常”。
它不是运行时检测,而是靠编译器静态分析函数声明中的 noexcept 说明符(包括隐式 noexcept 推导)来判断。
基本用法和语法
模板参数是两个类型:From 和 To。结果是一个 std::integral_constant:
立即学习“C++免费学习笔记(深入)”;
-
value == true表示存在至少一个从From到To的转换路径,且所有可行的转换函数(含构造函数、转换运算符)都标记为noexcept(或满足隐式 noexcept 条件); -
value == false表示:要么无法转换,要么至少有一个可行转换可能抛异常(例如构造函数没写 noexcept,或写了noexcept(false))。
示例:
struct A { A(int) noexcept {} };struct B { B(int) {} }; // 不 noexcept
static_assert(std::is_nothrow_convertible_v
static_assert(!std::is_nothrow_convertible_v
和 std::is_convertible 的关键区别
-
std::is_convertible:只关心“语法上能不能转”,不管会不会抛异常; -
std::is_nothrow_convertible:在可转换的前提下,进一步要求“所有参与转换的函数都 noexcept”——它是更强的约束。 - 注意:即使
To的构造函数是noexcept,但如果From的隐式转换运算符(如operator int())可能抛异常,整体仍判为false。
典型应用场景
- 为
std::variant实现emplace或赋值时,确保新值的构造不破坏异常安全保证; - 编写泛型容器或智能指针时,在 move/swap 等操作中启用
noexcept优化(如std::vector::resize是否调用移动而非拷贝); - 配合
if constexpr在编译期分支:当转换确定不抛异常时,走更高效的路径(比如省去 try/catch 包装); - 自定义类型设计时,作为 SFINAE 或 requires 子句的一部分,约束模板参数的行为契约。
基本上就这些。它不大起眼,但在构建高可靠性、高性能、强异常安全的泛型库时,是个关键的元编程工具。











