mercredi 24 avril 2019

Why does std::is_nothrow_move_constructible return false with user-declared move constructor?

everyone.

I'm trying to add noexcept specifications and static_asserts to my class. To accomplish this goal I've made a small research on how std::is_nothrow_move_constructible works.

I've got strange results:

  • std::is_nothrow_move_constructible<A>::value for a class A with only default-constructor declared by user returns 'true'. This is ok.
  • For a class A with a default-constructor and a move constructor without noexcept keyword it returns false and I get a compiler error. This is fine too.
  • The strange part: if I define a user-declared move constructor with noexcept declaration I still get an error. This does not depend on other declarations/definintions, like having a destructor or not. See the example below:
#include <type_traits>    
class A
{
        A() {}
        A(A&& b) noexcept {} // compile error on static_assert
        ~A() noexcept {}
};

int main()
{

  static_assert(std::is_nothrow_move_constructible<A>::value, 
    "require noexcept movectr"); 
        return 0;
}

Here is a compilation command:

g++ -o static_assert ./static_assert.cpp --std=c++11

The OS is Linux (Gentoo Chroot in Fedora 25 Host), Compiler: gcc (Gentoo 4.8.3 p1.1, pie-0.5.9) 4.8.3

I've tried an online compiler and I've got the same result (see http://cpp.sh/9mawg), so this seems to be something about the mechanics of these traits in general and not my OS/compiler setup.

Can somebody clear the fog around is_nothrow_move_* traits and point me at the reason of such a behaviour?

Aucun commentaire:

Enregistrer un commentaire