在 class 中使用 static_assert - 怎么样?

using static_assert in a class - how?

我试图简化在编译时检查一个值到新类型的转换是否保留该值。 STL 中可能有一些东西可以为我做这件事,但我没有看到,所以我写了一个。它有效,但我想将其转换为 class 以便其他人使用起来更简单一些。我无法让它工作,我觉得我遗漏了一些明显的东西。

这很好用:

    template <typename T, typename Q>
    constexpr bool checkV(const Q x) 
    {return x == (T)x && ((x < 0) == ((T)x < 0));}

    static_assert(checkV<unsigned int>(-7), "No");

但是这个调用很笨拙,所以我想要更像

的东西
    CheckIt<unsigned int>(-7)

所以我尝试了

    template<typename T>
    class CheckIt {public:
      template<typename Q>
      constexpr CheckIt(const Q x) {static_assert(checkV<T>(x), "No");}
};

我尝试了各种const 和constexpr 的组合(发现参数不能是constexpr,这很烦人)。我尝试的所有操作都会导致 g++ 抱怨 x 不是构造函数中的常量表达式。

我错过了什么? checkv 和构造函数总是使用常量调用,例如 -7。 checkv() 很乐意在编译时进行评估,我看不出在哪里使用构造函数来包装会给编译器增加任何额外的负担,但显然它确实如此。注意我需要它在 C++11 中工作,但我看不到更高版本的帮助。我在运行时使用断言检查没有问题,但我想要常量的编译时解决方案。 TIA.

将变量传递给函数将不起作用,因为它不是常量表达式,因此 static_assert 不会接受它。

您可以尝试将值作为模板参数传递。

template <typename T, typename Q>
constexpr bool checkV(const Q x)
{
    return x == static_cast<T>(x) && ((x < 0) == (static_cast<T>(x) < 0));
}

template <typename T, typename Q, Q N>
void CheckIt() {
    static_assert(checkV<T, Q>(N));
}


int main() {
    constexpr auto val = -7;
    CheckIt<unsigned int, decltype(val), val>();
}

但也不是很干净。

编辑:您还可以使用 "good" 旧宏的

#define CheckIt(x,y) static_assert(checkV<x, decltype(y)>(y));

int main() {
    CheckIt(unsigned int, -7);
}