C++ std::的奇怪行为是不可破坏的吗
以下代码触发了C++ std::的奇怪行为是不可破坏的吗,c++,c++11,exception,exception-handling,C++,C++11,Exception,Exception Handling,以下代码触发了static\u 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
static\u 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()
{
}
发生以下情况:
nothrow_destructible_bug.cc:20:1: error: static assertion failed: That's odd
static_assert( std::is_nothrow_destructible< Foo >::value, "That's odd" );
^
nothrow\u destructible\u bug.cc:20:1:错误:静态断言失败:这很奇怪
静态断言(std::是可破坏的::值,“这很奇怪”);
^
为什么仅仅使用
Foo
在一个不相关的类中实例化一个模板就会使它失去noexcept
状态?我认为这是一个编译器错误,但我尝试了gcc和clang的所有最新版本,它们似乎都给出了相同的错误。在使用Tmpxx
时,Foo
是一个不完整的类型。这违反了使用的一个先决条件是\u nothrow\u destructible
,并且它的使用是未定义的行为。UB的一种可能性是,不可破坏
为假
评论Tmp的使用将避免这个问题。由于模板在使用之前不会实例化,因此注释掉构造函数也可以避免问题,因为模板尚未实例化
在
Bar
之前移动struct Foo
的定义也应该可以避免这个问题。你的意思是检查是否可破坏
而不是是否可破坏
?“是否可破坏[sic]将是错误的。”它只是简单的UB。任何事情都有可能发生。我想知道这些情况是什么,我在哪里可以了解到它们?事实上,在这种情况下,有一个沉默的UB令人害怕me@dragonroot它们都在语言标准文档中。如果您的is_nothrow_destructible文档没有提到该类型需要是一个完整的类型,那么您应该为其提交一份缺陷报告。
nothrow_destructible_bug.cc:20:1: error: static assertion failed: That's odd
static_assert( std::is_nothrow_destructible< Foo >::value, "That's odd" );
^