用实际代码替换define语句



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

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

#define True GetObject(true)

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

但我想不出一种方法来制作它,所以下面的代码:

int main() {
auto c = True;
return 0;
}

在编译时变成这样:

int main() {
auto c = GetObject(true);
return 0;
}

摘要:我想要一个完全替代";定义";作为代码,我发现了一个类似于内联函数的东西可能会有所帮助,但有没有一种方法可以生成内联变量?

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

inline Object True = GetObject(true);

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

注意2:如果可能的话,我希望避免将True转为True()

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

谢谢!!!

编辑1

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

返回的值将是相同的,但函数调用是必需的

编辑2

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

宏名称True是完全随机的,它可以被命名为完全不同的东西(我只是用它来测试)

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

我还需要大量更新类,以便在构造函数中添加更多常量。我需要一些简单的方法来完成,我认为在我的10个头/源中的每一个中替换每个实例是不好的

具有表示"True"和其他状态的值。

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

以下内容在原理上可能与您的代码相似。它用#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

但是有办法生成内联变量吗?

是的,由于C++17,可以定义内联变量。内联变量和其他命名空间范围变量相同,只是您可以在一个可能包含在多个转换单元中的头中定义它们。示例:

inline auto True = GetObject(true);

我想要一个精确的";定义";作为代码

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

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

注意2:如果可能的话,我希望避免将True转换为True()

如果您想进行函数调用,这是一件不好的事情。我建议你放弃一种欲望。

我希望True每次都调用GetObject(true)函数

那么True()是没有宏的情况下最好的。

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

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

最新更新