当我想使用一些辅助结构和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
值?是否有另一种干净的方法可以快速检查这个属性?
答案 0 :(得分:3)
简单的答案可能只是添加另一个static_assert
:
template<size_t ... Sizes>
struct Test
{
static constexpr size_t Final = check_sizes<Sizes...>();
static_assert(Final > 0, "");
};
但这会导致两个单独的静态断言失败。如果这对您来说是个问题,您可以确保check_sizes
或Final
以某种其他方式使用,必须在模板类实例化时进行评估,而不实例化任何成员,例如:
template<size_t ... Sizes>
struct Test
{
static constexpr decltype(check_sizes<Sizes...>(), size_t()) Final = check_sizes<Sizes...>();
};
另一个选择:如果Test<...>
是一个预期正常构建的类,你可以确保以某种方式从构造函数中使用Final
。