Puppy
Puppy

Reputation: 146978

boost::is_nothrow_move_constructible implementation

I'm giving the new VS 2015 Preview a go, and I'm having some trouble with Boost. But after tracing the problem, I don't understand how it ever worked on any compiler.

I have an unordered_map<K, boost::variant<std::unordered_map<int, std::unique_ptr<T>>>>. This fails to compile because the boost::variant apparently tries to copy-construct the unordered_map inside it- based on the result of the boost::is_nothrow_move_constructible trait, which is indeed boost::false_type.

This reveals the definition of boost::is_nothrow_move_constructible as

template <class T>
struct is_nothrow_move_constructible_imp{
    BOOST_STATIC_CONSTANT(bool, value =(
        ::boost::type_traits::ice_and<
            ::boost::type_traits::ice_or<
                ::boost::has_trivial_move_constructor<T>::value,
                ::boost::has_nothrow_copy<T>::value
            >::value,
            ::boost::type_traits::ice_not< ::boost::is_array<T>::value >::value
        >::value));
};

Er, what about non-trivial noexcept move constructors, like many, many classes have? How can this definition function on other compilers?

Upvotes: 2

Views: 260

Answers (1)

Puppy
Puppy

Reputation: 146978

Turns out that the real confusion here is that it never did work on Visual Studio. I guess that must have been only optional and not variant where I previously used move-only types. It seems that variant effectively cannot support move-only types on Visual Studio for any current version, and my memories of it working on VS2013 are clearly incorrect.

I ended up simply specializing the trait for the types I'm using. Hacky but functional.

Upvotes: 1

Related Questions