在C++中使用NaN?

Jos*_*ley 32 c++ floating-point nan

在C++中使用NaN的最佳方法是什么?

我发现std::numeric_limits<double>::quiet_NaN()std::numeric_limits<double>::signaling_NaN().我想signaling_NaN用来表示一个未初始化的变量,如下所示:

double diameter = std::numeric_limits<double>::signaling_NaN();
Run Code Online (Sandbox Code Playgroud)

但是,这会在分配时发出信号(引发异常).我希望它在使用时引发异常,而不是在赋值时引发异常.

有没有办法在signaling_NaN没有提出转让例外的情况下使用?是否有一个好的,可移植的替代品signaling_NaN会在使用时引发浮点异常?

Jos*_*ley 11

在进一步研究之后,它看起来像signaling_NaN提供的一样无用.如果启用了浮点异常,则调用它将计为处理信令NaN,因此它会立即引发异常.如果禁用浮点异常,则处理信令NaN会自动将其降级为安静的NaN,因此signaling_NaN无论如何都不起作用.

Menkboy的代码工作,但试图使用信号NaN运行到其他的问题:有没有可移植的方法来启用或禁用浮点异常(如提到这里这里),如果你依靠的例外被启用,第三方的代码可能禁用它们(如描述在这里).

所以看来Motti的解决方案真的是最好的选择.


Mot*_*tti 9

NAN表示的意思是当CPU遇到它时会触发一个信号(因此名称).如果要检测未初始化的变量,则在编译器上提高警告级别通常会检测使用未初始化值的所有路径.如果失败,你可以使用一个包装类来存储一个布尔值,如果该值被初始化:

template <class T>
class initialized {
    T t;
    bool is_initialized;
public:
    initialized() : t(T()), is_initialized(false) { }
    initialized(const T& tt) : t(tt), is_initialized(true) { }
    T& operator=(const T& tt) { t = tt; is_initialized = true; return t; }
    operator T&() {
         if (!is_initialized)
             throw std::exception("uninitialized");
         return t; 
   }
};
Run Code Online (Sandbox Code Playgroud)

  • `boost :: optional <T>`是一个很好的替代方法,适用于返回值,局部变量和成员.此外,它不会调用默认构造函数,并且大部分都使用引用类型. (4认同)