C++预处理器和重载问题

发布于 2024-10-16 10:30:32 字数 660 浏览 2 评论 0原文

我有以下问题:

让我们考虑一下

#define SET callMe
#define COLUMN(x) #x

,在程序的主要块中,我们有以下行: SET(COLUMN(price)="hi"); 在预处理器运行后翻译为:

#callMe("price"="hi"); 

我需要函数 callMe 签名为 callMe(string str) 因此,我们必须做一些事情来将 "price"="hi" 变为 "price=hi" 并让 callMe< /code> 函数来处理剩下的问题。最后要说明的是,我描述的所有程序都是 Table 类的一部分。

我唯一的选择是重载运算符 = ,以便将 "price"="hi" 转换为想要的,但我无法得到我应该重载的内容,因为我首先想到将以下重载

#std::string operator=(std::string str) 作为 Table 类的成员函数,但似乎我无法让它走上正轨。

关于如何实现所需操作的任何线索?

I have the following problem:

Let's consider we have

#define SET callMe
#define COLUMN(x) #x

and in our main block of our program we have the following line:
SET(COLUMN(price)="hi"); which after the preprocessor running is translated to:

#callMe("price"="hi"); 

I need function callMe signature to be callMe(string str) so that leaves us to have to make something to make the "price"="hi" to "price=hi" and let callMe function to handle the rest of the problem. Last thing to state is that all this program I describe is a part of a Table class.

The only option I have is overload the operator = so the "price"="hi" translated to the wanted one, but I can't get what I should overload because I first thought that doing the following overload

#std::string operator=(std::string str) as a member function of the Table class but it seems I can't get it right on track.

Any clues of how I can achieve the wanted operations?

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

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

发布评论

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

评论(4

以酷 2024-10-23 10:30:32

这对你有好处吗?

#define SECOND_PASS(x) callMe(#x)
#define COLUMN(x) x
#define SET(x) SECOND_PASS(x)

结果是:

callMe("price=\"hi\"");

这本质上是让预处理器在转换为字符串之前删除 COLUMN。

Is this any good to you?

#define SECOND_PASS(x) callMe(#x)
#define COLUMN(x) x
#define SET(x) SECOND_PASS(x)

which results in:

callMe("price=\"hi\"");

This essentially gets the preprocessor to remove COLUMN before converting to a string.

隔纱相望 2024-10-23 10:30:32

要获得您想要的结果,您必须将代码编写为 SET(COLUMN(price)"=hi")

您无法为内置类型重载 operator=()。这样做是为了保持理智等原因。

C++ 重载并不是为了让您强制编译器解析不同的语言。

PS Table 类中的重载 operator=() 仅处理 Table 位于 左侧的情况= 。这将需要 COLUMN(x) 返回一个 Table 对象,这可能不是您想要的。您可以使用适配器类来获得此效果,但 COLUMN(x) 的语法不包括该列来自哪个表,因此您也陷入困境。

一种解决方案看起来像这样:

class ColumnSetter
{public:
    ColumnSetter(const char* name): name(name), value(0) {}
    ColumnSetter& operator=(const char* value_) { value = value_; }
    operator std::string const &() const { std::string result(name);
        if(value) { result.append('='); result.append(value); } return result; }
private:
    const char* name;
    const char* value;
};

#define COLUMN(x) ColumnSetter(#x)

void callMe(const std::string& param);

重新格式化并内联到您拥有的任何编码标准。

To get what you want, you would have to write your code as SET(COLUMN(price)"=hi").

You can't overload operator=() for a built-in type. This is done for sanity maintenance, among other reasons.

C++ overloading is not intended to allow you to force the compiler to parse a different language.

P.S. Overloading operator=() in the Table class only handles the case where a Table is on the left-hand side of the =. That would require COLUMN(x) to return a Table object, probably not what you want. You could use an adaptor class to get this effect, but the syntax of COLUMN(x) doesn't include which table this column is from, so you're stuck there too.

One way out there solution would look something like this:

class ColumnSetter
{public:
    ColumnSetter(const char* name): name(name), value(0) {}
    ColumnSetter& operator=(const char* value_) { value = value_; }
    operator std::string const &() const { std::string result(name);
        if(value) { result.append('='); result.append(value); } return result; }
private:
    const char* name;
    const char* value;
};

#define COLUMN(x) ColumnSetter(#x)

void callMe(const std::string& param);

Reformat and de-inline to whatever coding standards you have.

小情绪 2024-10-23 10:30:32

你的意思是像

#define SET(x) (CallMe(x))

ps - 关于使用预处理器的通常免责声明

You mean like

#define SET(x) (CallMe(x))

ps - usual disclaimer about using the preprocessor

半衾梦 2024-10-23 10:30:32

这应该通过重载各种逻辑运算符以创建抽象语法树而不是实际执行操作的类来完成。然后,您可以将各种 SQL 表达式表达为 C++ 代码,并获得一个抽象语法树,然后将其序列化为 SQL WHERE 子句。

这并不难,如果你小心的话,它会非常有效。这比尝试使用预处理器黑客技术来创建 SQL 表达式生成器要好得多。

This should be done with classes that overload the various logical operators to create an abstract syntax tree instead of actually performing the operation. Then you can express various SQL expressions as C++ code and get an abstract syntax tree out which can then be serialized into an SQL WHERE clause.

This isn't very hard, and if you are careful about it, it will be pretty efficient. It's much better than trying to use preprocessor hackery to create an SQL expression builder.

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