强制评估constexpr静态成员

时间:2014-12-29 19:19:04

标签: c++ templates c++11 constexpr

当我想使用一些辅助结构和constepxr函数检查某些模板参数的有效性时,我遇到了问题。只要没有对静态constexpr成员的引用,我想初始化编译器决定不评估表达式。我使用的代码如下:

#include <cstddef>
#include <iostream>

#define CONSTEXPR static constexpr
using namespace std;

template<size_t ... Sizes>
struct _size_check_impl
{
    static_assert(sizeof...(Sizes) != 0, "Dimension has to be at least 1");
    CONSTEXPR size_t dimension = sizeof...(Sizes);
};

template<size_t ... Sizes>
constexpr size_t check_sizes()
{
    return _size_check_impl<Sizes...>::dimension;
}

template<size_t ... Sizes>
struct Test
{
    static constexpr size_t Final = check_sizes<Sizes...>();
};

int main()
{
    Test<> a; // This shouldn't get through the static assert
    Test<1, 2> b; // Passing
    Test<2> c; // Passing
    // cout << Test<>::Final; // With this it works just fine, bc Final is accessed
    return 0;
}

有没有办法可以做到这一点,一些代理依赖会强制编译器在评估constexpr时评估Final值?是否有另一种干净的方法可以快速检查这个属性?

1 个答案:

答案 0 :(得分:3)

简单的答案可能只是添加另一个static_assert

template<size_t ... Sizes>
struct Test
{
    static constexpr size_t Final = check_sizes<Sizes...>();
    static_assert(Final > 0, "");
};

但这会导致两个单独的静态断言失败。如果这对您来说是个问题,您可以确保check_sizesFinal以某种其他方式使用,必须在模板类实例化时进行评估,而不实例化任何成员,例如:

template<size_t ... Sizes>
struct Test
{
    static constexpr decltype(check_sizes<Sizes...>(), size_t()) Final = check_sizes<Sizes...>();
};

另一个选择:如果Test<...>是一个预期正常构建的类,你可以确保以某种方式从构造函数中使用Final