想知道有用的用途operator ,
我正在尝试创建一组帮助器对象,以便更轻松地从 C++ 代码构建 DB 查询。我的想法是利用operator ,
类似于数据库调用的创建指令的顺序。辅助对象如下:
class Fields
{
public:
Fields &operator ,(const std::string &s)
{
SQL.append(s).append(1, ',');
return *this;
}
Fields &operator ,(const Fields &f)
{
std::string Result = f;
SQL.append(Result);
return *this;
}
virtual operator std::string() const = 0;
protected:
std::string SQL;
};
template <const char *INSTRUCTION> struct Instruction : public Fields
{
operator std::string() const
{
std::string Result(INSTRUCTION);
return Result.append(SQL);
}
};
然后,使用正确typedef
的 s 和值,此方法允许执行以下操作:
extern const char SQL_SELECT[] = "SELECT ";
extern const char SQL_FROM[] = "FROM ";
extern const char SQL_WHERE[] = "WHERE ";
extern const char SQL_ORDER_BY[] = "ORDER BY ";
typedef Instruction<SQL_SELECT> SELECT;
typedef Instruction<SQL_FROM> FROM;
typedef Instruction<SQL_WHERE> WHERE;
typedef Instruction<SQL_ORDER_BY> ORDER_BY;
std::string Query = ((SELECT(), "a", "b", "c"),
(FROM(), "A", "B"),
(WHERE(), "a = b AND c <> b"),
(ORDER_BY(), "a", "c"));
std::cout << Query;
这会产生这个输出:(SELECT a,b,c,FROM A,B,WHERE a = b AND c <> b,ORDER_BY a,c,
我正在处理我的版本中的尾随逗号,为了缩短示例省略了这部分),这是代码。
问题是指令ORDER BY
。该指令可以采用改变排序行为的最终操作数,我想(通过operator ,
)将枚举值传递给struct Instruction
实例:
enum ORDER
{
ASC,
DESC,
};
std::string OrderBy = (ORDER_BY(), "a", "c", DESC); // <---- Note the 'DESC' value.
但只想为Instruction<SQL_ORDER_BY>
实例启用此运算符,所以我尝试专门化模板:
template <> struct Instruction<SQL_ORDER_BY> : public Fields
{
Instruction() : order(ASC) {}
Fields &operator ,(const ORDER o)
{
order = o;
return *this;
}
operator std::string() const
{
std::string Result(SQL_ORDER_BY);
Result.append(SQL);
Result.append(order == ASC? "ASC": "DESC");
return Result;
}
private:
ORDER order;
};
AFAIK 这个专业化必须有三个operator ,
重载:
Fields &operator ,(const Fields &)
.Fields &operator ,(const std::string &)
.Fields &operator ,(const ORDER)
.
但是在创建专业化之后,查询字符串:
std::string Query = ((SELECT(), "a", "b", "c"),
(FROM(), "A", "B"),
(WHERE(), "a = b AND c <> b"),
(ORDER_BY(), "a", "c"));
结束具有值:SELECT a,b,c,FROM A,B,WHERE a = b AND c <> b,c,
。这就像 ifORDER_BY
被忽略,并且添加该DESC
值会导致编译错误:
std::string Query = ((SELECT(), "a", "b", "c"),
(FROM(), "A", "B"),
(WHERE(), "a = b AND c <> b"),
(ORDER_BY(), "a", "c", DESC)); // <-- cannot convert 'ORDER' to 'string'
似乎ORDER
值没有进入operator ,
专业化,但是在同一个命名空间上添加一个自由运算符可以修复编译错误:
std::string operator ,(const std::string &left, const ORDER right)
{
std::string Result(left);
return Result.append(1, ',').append(right == ASC? "ASC": "DESC");
}
但我真的认为这Fields &Instruction<SQL_ORDER_BY>::operator ,(const ORDER)
会被调用,所以我现在寻求一些建议:
- 为什么
Instruction<SQL_ORDER_BY>
在专门化模板后实例没有附加到查询字符串? - 为什么这些
ORDER
值没有调用Fields &operator ,(const ORDER)
专业化提供的值。 operator ,
有多少Instruction<SQL_ORDER_BY>
实例?
PS:所有这些努力都是出于自学的目的,该代码的几乎零行最终会出现在生产代码中,因此请避免对使用库或代码的实用性发表评论,
谢谢。
编辑:
删除他的答案的人建议在专业化中添加using Fields::operator std::string;
和using Fields::operator,;
行,这样做解决了忽略ORDER_BY
问题。