Search code examples
c++templatestype-traitsstatic-assert

Work around incomplete type in static assert


Is there a way to static_assert inside a class when the expression depends on the class type itself? Maybe delay the evaluation until the type is complete or after template instantiation?

Example code:

#include <type_traits>

template<typename T>
struct Test {
   T x = 0; // make non-trivial
   static_assert(std::is_trivial<Test<T>>::value, "");
};

int main() {
    // would like static assert failure, instead get 'incomplete type' error
    Test<int> test1;
    Test<float> test2;
    return 0;
}

Solution

  • Here's a solution using a helper class and a type alias for indirection. I believe this has no drawbacks.

    template<typename T>
    struct TestImpl {
        T x = 0; // make non-trivial
    };
    
    template<typename T>
    struct TestHelper {
        using type = TestImpl<T>;
        static_assert(std::is_trivial<type>::value, "");
    };
    
    template<typename T>
    using Test = typename TestHelper<T>::type;
    

    edit: Alternatively TestHelper can be moved into TestImpl:

    template<typename T>
    struct TestImpl {
        T x = 0; // make non-trivial
    
        struct Helper {
            using type = TestImpl;
            static_assert(std::is_trivial<type>::value, "");
        };
    };
    
    template<typename T>
    using Test = typename TestImpl<T>::Helper::type;