静态构件的力评估.

Force evaluation of constexpr static member

本文关键字:评估 构件 静态      更新时间:2023-10-16

当我想使用一些辅助结构和 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值?有没有另一种干净的方法来检查此属性的清洁和快速?

简单的答案可能是简单地添加另一个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