c++static-assert

Determine if objects stored in an std::vector are trivially copyable


This code doesn't compile, since the static assert fails.

#include <vector>
#include <type_traits>

class A {
};

int main()
{
    std::vector<A> v;
    static_assert(std::is_trivially_copyable<decltype(v[0])>::value);
    return 0;
}

If, on the other hand, I replace the decltype(v[0]) with A, then it compiles. The problem is that v[0] is of type reference to A rather than A. How can I make it work using v in some way?


Solution

  • std::vector has a value_type member that is the type given in the parameter list of the vector for the element type. Using that gives you

    static_assert(std::is_trivially_copyable<decltype(v)::value_type>::value);
    

    Alternatively you can remove the reference qualification from v[0] like

    static_assert(std::is_trivially_copyable<std::remove_reference<decltype(v[0])>::type>::value);
    // or if you want to remove all cv and ref qualifications
    static_assert(std::is_trivially_copyable<std::remove_cvref<decltype(v[0])>::type>::value);
    // or if you want to remove all cv, ref, and array qualifications
    static_assert(std::is_trivially_copyable<std::decay<decltype(v[0])>::type>::value);
    

    Do note that if you are using a newer version of C++ like C++17 or C++20 then you can use the _t and _v versions of the type traits to simplify the code to

    static_assert(std::is_trivially_copyable_v<decltype(v)::value_type>);
    
    static_assert(std::is_trivially_copyable_v<std::remove_reference_t<decltype(v[0])>>);
    
    static_assert(std::is_trivially_copyable_v<std::remove_cvref_t<decltype(v[0])>>);
    
    static_assert(std::is_trivially_copyable_v<std::decay_t<decltype(v[0])>>);