简体   繁体   English

在 class 中使用 static_assert - 怎么样?

[英]using static_assert in a class - how?

I'm trying to make it simple to check at compile time whether the conversion of one value to a new type preserves the value.我试图简化在编译时检查一个值到新类型的转换是否保留了该值。 There may be something in the STL that can do this for me, but I don't see it, so I wrote one. STL 里面可能有东西可以帮我做这个,但是我没有看到,所以我写了一个。 It works, but I wanted to convert it to a class in order to make the use a little simpler for others.它可以工作,但我想将其转换为 class 以便其他人使用更简单。 I can't get that to work and I feel like I'm missing something obvious.我无法让它发挥作用,我觉得我错过了一些明显的东西。

This works fine:这工作正常:

    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");

But the call is ungainly, so I wanted something more like但是这个电话很笨拙,所以我想要更像

    CheckIt<unsigned int>(-7)

and so I attempted所以我尝试了

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

I've tried various combinations of const and constexpr (and discovered parameters can't be constexprs, which is annoying).我尝试了 const 和 constexpr 的各种组合(发现参数不能是 constexpr,这很烦人)。 Everything I try results in g++ complaining that x is not a constant expression in the constructor.我尝试的所有结果都会导致 g++ 抱怨 x 不是构造函数中的常量表达式。

What am I missing?我错过了什么? checkv, and the constructor, are both always called with constants, like -7. checkv 和构造函数都始终使用常量调用,例如 -7。 checkv() is happy to evaluate at compile time and I can't see where using a constructor function to wrap that adds any additional burden to the compiler, but obviously it does. checkv() 很乐意在编译时进行评估,我看不出在哪里使用构造函数 function 进行包装,这给编译器增加了任何额外的负担,但显然确实如此。 Note I need this to work in C++11, but I don't see where later versions will help.注意我需要这个在 C++11 中工作,但我看不出以后的版本在哪里会有帮助。 I have no problems checking at runtime, with assert, but I want the compile time solution for constants.我在运行时使用断言检查没有问题,但我想要常量的编译时解决方案。 TIA. TIA。

Passing a variable to a function will not work, as it is not a constant expression, thus the static_assert will not accept it.将变量传递给 function 将不起作用,因为它不是常量表达式,因此 static_assert 不会接受它。

You can try passing the value as a template parameter.您可以尝试将该值作为模板参数传递。

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

But it's not much cleaner.但它并没有更干净。

edit: your can also use the "good" old macro's编辑:您也可以使用“好”的旧宏

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM