鉴于以下程序:
#include <cstdio>
#include <type_traits>
#include <utility>
struct EmptyClass {};
template <typename T, typename U>
struct Storage {
protected:
union Union {
T t;
U u;
} data;
char flag = false;
};
class AnotherEmptyClass {};
template <typename T, typename U>
class Derived : private Storage<T, U>, public AnotherEmptyClass {};
static_assert(std::is_standard_layout_v<Derived<char, EmptyClass>>);
int main() {
printf("Storage<char, EmptyClass>: %zu\n", sizeof(Storage<char, EmptyClass>));
printf("Derived<char, EmptyClass>: %zu\n", sizeof(Derived<char, EmptyClass>));
printf("Storage<char, char>: %zu\n", sizeof(Storage<char, char>));
printf("Derived<char, char>: %zu\n", sizeof(Derived<char, char>));
}
Run Code Online (Sandbox Code Playgroud)
这在 Linux 上输出 2 …
gcc 8和clang 7不接受以下代码,它们应该默认构造一个临时类型unsigned int:
unsigned int ui = unsigned int{};
Run Code Online (Sandbox Code Playgroud)
clang 7报告错误,例如
<source>:6:22: error: expected primary-expression before 'unsigned'
Run Code Online (Sandbox Code Playgroud)
Visual C++ 2015和2017接受此.
显然,这适用于诸如int或任何默认可构造类类型之类的类型.
这是正确的C++ 14代码(在这种情况下是clang和gcc的错误)?如果没有,为什么不呢?除了无符号类型之外的哪些类型会受到相同的限制?
以下代码无法使用Visual Studio 2017(15.5),gcc 6.4.0和clang 4.0.1进行编译,即静态断言失败:
struct Type
{
Type(Type&&) noexcept {}
~Type() noexcept(false) {}
};
static_assert(std::is_nothrow_move_constructible<Type>::value, "Type should be nothrow-move-constructible");
static_assert(std::is_nothrow_constructible<Type, Type&&>::value, "Type should be nothrow-constructible from Type&&");
Run Code Online (Sandbox Code Playgroud)
这是正确的C++标准吗?是否std::is_nothrow_move_constructible需要noexcept析构函数?为什么?
如果我使用这样的:
Type a;
Type b(std::move(a));
Run Code Online (Sandbox Code Playgroud)
a在第二个语句中没有调用析构函数.