检查 C++ 中的值定义

发布于 2024-07-12 12:41:05 字数 381 浏览 7 评论 0原文

我正在使用 C++ 工作,我需要知道标量值(例如 double)是否已“定义”。 如果需要的话,我还需要能够“undef”它:

class Foo {
public:
    double get_bar();

private:
    double bar;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( undefined(bar) )
        calculate_bar();
    return bar;
}

Is it possible in C++?

谢谢

I'm working in C++ and I need to know if a scalar value (for instance a double) is "defined" or not. I also need to be able to "undef" it if needed:

class Foo {
public:
    double get_bar();

private:
    double bar;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( undefined(bar) )
        calculate_bar();
    return bar;
}

Is it possible in C++?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

栀梦 2024-07-19 12:41:05

正如其他答案所说,C++没有这个概念。 不过,您可以轻松解决它。

您可以在构造函数中将 bar 初始化为未定义的值,通常为 -1.0 或类似的值。

如果您知道calculate_bar永远不会返回负值,您可以实现未定义的函数来检查< 0.0。

一个更通用的解决方案是使用一个 bool 来表示 bar 是否已定义,并且您在构造函数中将其初始化为 false,并且当您第一次设置它时将其更改为 true。 boost::optional 执行此操作一种优雅的模板化方式。

这就是您的代码示例的样子。

class Foo {
public:
    double get_bar();
    Foo() : barDefined(false) {}
private:
    double bar;
    bool barDefined;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( barDefined == false ) {
        calculate_bar();
        barDefined = true;
    }
    return bar;
}

As the other answers says, C++ doesn't have this concept. You can easily work around it though.

Either you can have an undefined value which you initialize bar to in the constructor, typically -1.0 or something similar.

If you know that calculate_bar never returns negative values you can implement the undefined function as a check for < 0.0.

A more general solution is having a bool saying whether bar is defined yet that you initialized to false in the constructor and when you first set it you change it to true. boost::optional does this in an elegant templated way.

This is what the code example you have would look like.

class Foo {
public:
    double get_bar();
    Foo() : barDefined(false) {}
private:
    double bar;
    bool barDefined;
    void calculate_bar() {
        bar = something();
    }
};

double Foo::get_bar() {
    if ( barDefined == false ) {
        calculate_bar();
        barDefined = true;
    }
    return bar;
}
深海夜未眠 2024-07-19 12:41:05

正如其他人指出的那样,没有什么比“未定义”状态更好的了。 但您可能想查看 boost.可选

As others pointed out, there is nothing like an "undefined" state. But you may want to look into boost.optional

千柳 2024-07-19 12:41:05

如果你的意思是在运行时,则不存在这样的事情。 如果 bar 从未初始化,它将具有随机位,具体取决于对象的分配方式(某些分配器会将新内存初始化为全零)。

编辑:由程序员在构造函数和/或手动初始化方法(如 init() )中处理对象状态

If you mean at run-time, there is no such thing. If bar is never initialized, it will have whatever random bits happen to be there, depending on how the object is allocated (some allocators will initialize new memory to all-zero).

edit: it's up to the programmer to handle object state in constructors and/or manual initialization methods like init()

感悟人生的甜 2024-07-19 12:41:05

C++ 没有原始类型的“未定义”状态。 最接近的 float/double 是 NAN,但这确实有不同的含义。

C++ does not have an "undefined" state for primitive types. The closest available for float/double would be NAN, but that really has a different meaning.

魔法少女 2024-07-19 12:41:05

为什么不维护一个单独的标志,该标志被初始化为 false,然后在计算 bar 时设置为 true。 然后可以通过再次将标志设置为 false 来“取消定义”。

if(!isBarValid)
{
    calculateBar();
    isBarValid = true;
}
return bar;

Why not maintain a separate flag that gets initialized to false and then gets set to true when bar is calculated. It can then be 'undefed' by setting the flag to false again.

if(!isBarValid)
{
    calculateBar();
    isBarValid = true;
}
return bar;
瑕疵 2024-07-19 12:41:05

这在 C/C++ 中是不可能的,基元将始终分配一个值(主要是垃圾,无论它之前的内存中的位置是什么,除非在声明时显式分配)。 我通常有一个占位符值(即指针为 0),表示未使用,但是这些值也必须显式分配。 如果您的 double 可以采用任何值,那么我建议您在它旁边放置一个布尔值,最初分配为 false,并在您想要进行计算时测试/设置该值。

This is not possible in C/C++, primitives will always a value assigned (mostly garbage, whatever was on that spot in memory before it, unless explicitly assigned at declaration). I's common to have a placeholder value (i.e. 0 for pointers) which denotes not-used, however these have to be explicitly assigned as well. If your double can take on any value, then I suggest you put a boolean next to it, assigned to false initially, and test/set that one when you want to do your calculation.

鱼忆七猫命九 2024-07-19 12:41:05

您必须使用额外的布尔值来完成此操作。

要使用额外的布尔值来实现,您可以尝试类似以下模板的逻辑:

template<typename T>
struct Defined
{
 bool defined;
 T value;
 Defined() : defined(false) {}
 Defined(const T& value_) : defined(true), value(value_) {}
 ... and perhaps other operators here ...
 ... to make this behave even more like a T ...
};

You must do it by using an extra boolean.

To implement using an extra boolean, you could try logic like the following template:

template<typename T>
struct Defined
{
 bool defined;
 T value;
 Defined() : defined(false) {}
 Defined(const T& value_) : defined(true), value(value_) {}
 ... and perhaps other operators here ...
 ... to make this behave even more like a T ...
};
不知在何时 2024-07-19 12:41:05

您可以尝试 Construct on first use idiom 和这样编写 get_bar()

double & get_bar()
{
    static double *bar = new double(something());
    return *bar;
}

当您调用 get_bar() 时,如果还没有人要求它,它会为您创建 bar 。 任何后续调用都只会返回 bar。 正如链接页面所说,这在技术上不会泄漏内存,因为操作系统会在程序退出时回收它。

更新:

将返回值更改为 double & 以允许您修改 bar

You could try the Construct on first use idiom and write get_bar() this way:

double & get_bar()
{
    static double *bar = new double(something());
    return *bar;
}

When you call get_bar() it will make bar for you if no one has asked for it yet. Any subsequent calls will just return bar. As the linked page says, this doesn't technically leak memory because the OS will reclaim it when the program exits.

UPDATE:

Changed the return value to double & to allow you to modify bar.

苦妄 2024-07-19 12:41:05

bar 初始化为某个值,当您在构造函数中调用 something() 函数时,该值永远不会发生。

例如:

Foo(): bar(-1)
{
}

然后在 get_bar 函数中检查值 -1

(嗯 Laserallan 也在 1 分钟前发布了这个答案:-( ;-) )

Initialize bar to some value which can never occur when you call the something() function in the constructor.

For example:

Foo(): bar(-1)
{
}

Then check for the value -1 in the get_bar function.

(hmmm Laserallan also posted that answer 1 minute before :-( ;-) )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文