c++ - std::is_nothrow_destructible 的奇怪行为

标签 c++ c++11 exception exception-handling

以下代码触发了 static_assert,尽管我认为它不应该触发:

#include <type_traits>

template< typename T >
struct Tmp
{
  ~Tmp() noexcept( std::is_nothrow_destructible< T >::value ) {}
};

struct Foo;

struct Bar
{
  // Comment this out for the problem to go away
  Tmp< Foo > xx;

  // ..or this
  Bar() {}
};

struct Foo {};

// This triggers
static_assert( std::is_nothrow_destructible< Foo >::value, "That's odd" );

int main()
{
}

编译时:

g++-4.9 -std=c++11 nothrow_destructible_bug.cc

发生以下情况:

nothrow_destructible_bug.cc:20:1: error: static assertion failed: That's odd
 static_assert( std::is_nothrow_destructible< Foo >::value, "That's odd" );
 ^

为什么仅使用 Foo 在不相关的类中实例化模板会使它失去其 noexcept 状态?我认为这是一个编译器错误,但我尝试了所有最新版本的 gcc 和 clang,它们似乎都给出了相同的错误。

最佳答案

你在哪里使用Tmp< Foo > xx , Foo是一个不完整的类型。这违反了使用 is_nothrow_destructible 的先决条件之一。 , 它的使用是未定义的行为。该 UB 的一种可能性是 is_nothrow_destructible是假的。

注释掉 Tmp 的使用将避免该问题。由于模板在使用之前不会被实例化,因此注释掉构造函数也可以避免该问题,因为模板尚未被实例化。

移动 struct Foo 的定义之前Bar也应该避免这个问题。

关于c++ - std::is_nothrow_destructible 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32960029/

相关文章:

c++ - 如何使用 rangev3 范围实现平面图

c# - 注入(inject)异常类

python - 为什么 Python 带有参数的 raise 需要解包?

java - 使用来自另一个异常的堆栈跟踪初始化异常?

c++ - gSOAP 从 2.8.10 升级到最新 (2.8.54) 没有 ns : for namespace on several XML tags

c++ - [basic.lookup]/1最后一句是什么意思?

c++ - 如何在 C++ 中逐个字符地从文件中读取?

c++ - 使用独立于模板的 enable_if 时,模板类的模板化友元函数出现链接器错误

c++ - 交换两个 boost::adjacency_list 图,类似于 std::swap

c++ - 使用 fstream 读取二进制文件并将结果存储在 vector 中