静态断言的非常量表达式

时间:2016-08-22 23:10:11

标签: c++ templates c++11 g++

previous question中,我试图在编译时弄清楚特定基本类型的特定转换(类型为double和返回)是否安全。

最终,我想出了以下代码:

#include <limits>
#include <vector>

template<class one>
class test {
    typedef typename one::value_type v; //My code actually takes std:: containers, not the type directly, so get the type.
    typedef std::numeric_limits<v> limits; //Easier to read

    static_assert(limits::max()==v(double(limits::max())),"MEANINGFUL ERROR MESSAGE"); //See if the conversion works correctly 
};

当声明为“安全”类型时,如:

test<std::vector<int> > a;

它编译得很好。但是当它使用无法正确转换的类型进行编译时,例如:

test<std::vector<unsigned long long> > b;

它没有像我预期的那样使断言失败,而是无法使用错误消息进行编译(使用带有--std=c++11的g ++ 4.7.1和5.3.0):

test2.cpp: In instantiation of ‘class test<std::vector<long long unsigned int> >’:
test2.cpp:11:40:   required from here
test2.cpp:8:5: error: non-constant condition for static assertion
     static_assert(limits::max()==v(double(limits::max())),"MEANINGFUL ERROR MESSAGE");

我认为它仍然可以完成工作(不会在出现问题时进行编译,但我仍然无法弄清楚为什么limits::max()==v(double(limits::max()))不能算作一个恒定的条件,我真的不知道就像它使错误信息不易理解的事实一样。我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

我刚刚想出了一个糟糕的解决方案:

#include <limits>
#include <vector>

template<class one>
class test {
    typedef typename one::value_type v; //My code actually takes std:: containers, not the type directly, so get the type.
    typedef std::numeric_limits<v> limits; //Easier to read

    static_assert(double(limits::max())!=double(limits::max())+1),"MEANINGFUL ERROR MESSAGE"); //Once the value is large enough that integers are not exactly representable, x==x+1 for doubles. 
};

我仍然希望我能找到更好的解决方案。这在某种程度上感觉不对,我不确定它在所有情况下都会起作用。至少我需要单独处理浮点转换。