Work around incomplete type in static assert

只谈情不闲聊 提交于 2019-12-10 09:32:18

问题


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;
}

回答1:


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;



回答2:


You can define a destructor and put the static_assert there, at least with g++ 5.4 -std=c++11 this works.




回答3:


(moving from the comments)

You can add an intermediate class to keep the logic, and let your clients instantiate a derived one, which just contains the static_asserts

#include <type_traits>

template<typename T>
struct TestImpl {
    T x = 0; // make non-trivial
};

template<typename T>
struct Test : TestImpl<T> {
    static_assert(std::is_trivial<TestImpl<T>>::value, "");
    using TestImpl<T>::TestImpl; // inherit constructors
};


来源:https://stackoverflow.com/questions/42779120/work-around-incomplete-type-in-static-assert

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!