C++预处理器和重载问题
我有以下问题:
让我们考虑一下
#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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这对你有好处吗?
结果是:
这本质上是让预处理器在转换为字符串之前删除 COLUMN。
Is this any good to you?
which results in:
This essentially gets the preprocessor to remove COLUMN before converting to a string.
要获得您想要的结果,您必须将代码编写为
SET(COLUMN(price)"=hi")
。您无法为内置类型重载
operator=()
。这样做是为了保持理智等原因。C++ 重载并不是为了让您强制编译器解析不同的语言。
PS
Table
类中的重载operator=()
仅处理Table
位于左侧的情况= 。这将需要 COLUMN(x) 返回一个 Table 对象,这可能不是您想要的。您可以使用适配器类来获得此效果,但 COLUMN(x) 的语法不包括该列来自哪个表,因此您也陷入困境。
一种解决方案看起来像这样:
重新格式化并内联到您拥有的任何编码标准。
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 theTable
class only handles the case where aTable
is on the left-hand side of the=
. That would requireCOLUMN(x)
to return aTable
object, probably not what you want. You could use an adaptor class to get this effect, but the syntax ofCOLUMN(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:
Reformat and de-inline to whatever coding standards you have.
你的意思是像
#define SET(x) (CallMe(x))
ps - 关于使用预处理器的通常免责声明
You mean like
#define SET(x) (CallMe(x))
ps - usual disclaimer about using the preprocessor
这应该通过重载各种逻辑运算符以创建抽象语法树而不是实际执行操作的类来完成。然后,您可以将各种 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.