用实际代码替换 define 语句

Replacing define statement with actual code

我知道 #define 不太好用,我不确定这是否重复,但我找不到最好的方法:

我有一个程序使用如下定义:

#define True GetObject(true)

我需要用实际代码替换定义语句

但我想不出办法,所以下面的代码:

int main() {

  auto c = True;

  return 0;
}

在编译时变成这样:

int main() {

  auto c = GetObject(true);

  return 0;
}

总结: 我想要将“define”完全替换为代码,我发现了类似内联函数的东西 可以提供帮助,但是有没有办法制作内联变量?

我尝试了以下但最终出现错误

inline Object True = GetObject(true);

注意:我不能使Object/GetObject成为constexpr class

注意 2:如果可能的话,我想避免将 True 变成 True()

这基本上是一个用于教育目的的问题,但我想在我正在编写的一个小型图书馆中使用它,如果你能告诉我最好的方法是什么,我会很高兴

谢谢!!!

编辑 1

由于上面第一个不是很清楚,我希望True每次都调用GetObject(true)函数

返回值将相同,但需要调用函数

编辑 2

我认为没有必要对此进行解释,但是,我正在创建的库是一个简单的层(对此并不重要),

宏名True完全是随机的,可以起个完全不同的名字(我只是用来测试的)

宏用于创建一个 Class,我需要在我的代码中大量使用它,我还需要它来创建 class 的新实例(不仅仅是一个副本)

我还需要更新 class 很多所以要在构造函数中添加更多常量我需要有一些简单的方法来做,我认为每个都进去不是很好我的 10 headers/sources 并替换每个实例

与代表 'True' 和其他状态的值。

关于删除 () 的部分是因为我认为在看起来像变量(或者可能是某种编译时常量?)的东西中看到很多括号是不方便的

but is there a way to make an inline variable?

是的,自 C++17 起可以定义内联变量。内联变量与其他命名空间作用域变量相同,除了您可以在 header 中定义它们,它可能包含在多个翻译单元中。示例:

inline auto True = GetObject(true);

I want an exact replacement of "define" as code

变量不会以与宏替换完全相同的方式运行。 GetObject 函数将只调用一次来初始化变量,而不是每次宏扩展为函数调用时调用一次。

如果你想有一个函数调用,那么理想的解决方案是显式编写一个函数调用,括号是语法的一部分。

NOTE 2: I'd like to avoid turning True to True() if that's possible

如果您想进行函数调用,这是一件很糟糕的事情。我建议放弃你的一个愿望。

I'd like True to call GetObject(true) function every time

那么 True() 是没有宏的最佳选择。

或者,如果您要在生成的实例上调用方法,让它们成为自由函数并让它们为自己创建一个实例:

namespace True
{
    void foo()
    {
        TrueObj obj(true);
        // ...
    }
}
True::foo();

以下可能与您的代码在原理上相似。 它用 #define 解决并为每个 Object 设置一个 serialno 并在控制台打印一些东西:

#define True GetObject(true)
#define False GetObject(false)

#include <iostream>
using namespace std;

class Object {
public:
    Object(bool b, int serial) : _b(b), _serialno(serial) {};

    bool _b;
    int _serialno;
};

Object GetObject(bool b) {
    static int curserial = 0;

    Object result(b, ++curserial);

    cout << "Created Object with serialno " << result._serialno << " and value " << boolalpha << result._b << endl;
    return result;
}

int main() {
    auto c = True;
    auto d = True;
    auto e = False;

    return 0;
}

生成输出

Created Object with serialno 1 and value true
Created Object with serialno 2 and value true
Created Object with serialno 3 and value false

现在我们把它改成没有'#define'的相同结果:

#include <iostream>
using namespace std;

class Object;
void GotObject(Object& o);

class Object {
public:
    Object(bool b) : _b(b), _serialno(++curserial) {};
    Object(const Object& other) : _b(other._b), _serialno(++curserial) {
        GotObject(*this);
    };

    bool _b;
    int _serialno;

    inline static int curserial = 0;
};

void GotObject(Object& o) {
    cout << "Created Object with serialno " << o._serialno << " and value " << boolalpha << o._b << endl;
}

inline Object True(true);
inline Object False(false);

int main() {
    auto c = True;
    auto d = True;
    auto e = False;

    return 0;
}

输出:

Created Object with serialno 3 and value true
Created Object with serialno 4 and value true
Created Object with serialno 5 and value false

每次我们将 TrueFalse 的值分配给新变量时,复制构造函数都会被调用并可以执行任何操作,无论您在 GetObject.

中做了什么

小变体:如果我们选择这个替代的自定义构造函数而不是代码中的那个,

    Object(bool b) : _b(b), _serialno(0) {};

我们将得到输出:

Created Object with serialno 1 and value true
Created Object with serialno 2 and value true
Created Object with serialno 3 and value false

不同之处在于,serialno 是否也为 TrueFalse 本身计算,或者仅在将它们分配给变量后计算。

对于生成 TrueFalse 调用第一个构造函数,对于以下对其他变量的赋值,调用第二个构造函数。

您还可以在 Object 中保留一个 bool _original 变量以仅调用 GetObject(),它说明您是从原始 True 还是从 False 复制.仅 TrueFalse 为真。您可以通过调用特殊的构造函数来识别它们。如果你想让它安全使用,你可以把那个构造函数设为私有,这样它就只能被友元函数或静态工厂方法调用。

在下面的代码中,从 cf 的分配不会调用 GotObject。

#include <iostream>
using namespace std;

class Object;
void GotObject(Object& o);

class Object {
public:
    Object(bool b) : _b(b), _serialno(0), _original(true) {};
    Object(const Object& other) : _b(other._b), _original(false), _serialno(0) {
        if (other._original)
            GotObject(*this);
    };

    bool _original;
    bool _b;
    int _serialno;
};

void GotObject(Object& o) {
    static int curserial = 0;
    o._serialno = ++curserial;

    cout << "Created Object with serialno " << o._serialno << " and value " << boolalpha << o._b << endl;
}

inline Object True(true);
inline Object False(false);

int main() {
    auto c = True;
    auto d = True;
    auto e = False;
    auto f = c;

    return 0;
}

输出:

Created Object with serialno 1 and value true
Created Object with serialno 2 and value true
Created Object with serialno 3 and value false