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

时间:2011-02-07 20:53:24

标签: c++ c-preprocessor

我有以下问题:

让我们考虑一下

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

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

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

我需要将callMe签名设为callMe(string str),这样我们就必须制作一些内容以使"price"="hi"转换为"price=hi"并让callMe起作用处理剩下的问题。最后要说的是我描述的所有程序都是Table类的一部分。

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

#std::string operator=(std::string str)作为Table类的成员函数,但似乎我无法正常运行。

有关如何实现有用操作的任何线索?

4 个答案:

答案 0 :(得分:3)

这对你有好处吗?

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

导致:

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

这实际上使预处理器在转换为字符串之前删除了COLUMN。

答案 1 :(得分:1)

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

您不能为内置类型重载operator=()。除了其他原因之外,这样做是为了保持理智。

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

P.S。在operator=()类中重载Table仅处理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);

重新格式化并删除您拥有的任何编码标准。

答案 2 :(得分:0)

你的意思是

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

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

答案 3 :(得分:0)

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

这不是很难,如果你小心,它会很有效率。它比尝试使用预处理程序hackery创建SQL表达式构建器要好得多。