- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
想知道 operator ,
的有用用途我正在尝试创建一组辅助对象,以便更轻松地从 C++ 代码构建数据库查询。我的想法是利用 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,
(我正在处理我版本中的尾随逗号,为了缩短示例省略了这部分),here is the code .
问题是指令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;
};
据我所知,这个专业必须有三个 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,
.这就像 ORDER_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
问题。
最佳答案
问题是由于您对 ,
的过载造成的Instruction<SQL_ORDER_BY>
中的运算符Fields
的子类隐藏父类(super class)中的重载运算符。这正是 C++ 中函数调用解析的工作方式:名称查找首先发生,一旦找到某个 namespace 中的一组名称 就停止;然后,执行重载决议。
问题在 this related article by Herb Sutter 中解释。 .这篇文章与您的问题并不完全相关,但包含解决方案。特别是,请查看“示例 2a”。
你必须使用 using
指令导入 Field
基类的运算符重载到派生类的范围内,所以你重载了 ,
在Instruction<SQL_ORDER_BY>
不会隐藏它们。
以这个小程序为例:
#include <iostream>
#include <string>
using namespace std;
struct A // Class A contains two overloads of operator ,
{
void operator , (int) { cout << "A::operator , (int)" << endl; }
void operator , (string) { cout << "A::operator , (string)" << endl; }
};
struct B : A // Class B contains only *one* overload of operator ,
// Overloads coming from `A` are *hidden* by this one
{
void operator , (double) { cout << "B::operator , (double)" << endl; }
};
int main()
{
A a;
a, 1; // "A::operator , (int)" will be printed to std out
a, "hello"; // "A::operator , (string)" will be printed to std out
B b;
b, 3.0; // "B::operator , (double)" will be printed to the std out
b, "hello"; // Nothing in the standard output!
}
但是,如果您更改 B
的定义这样:
struct B : A
{
using A::operator ,; // <-- Brings A's overloads into scope!
void operator , (double) { cout << "B::operator , (double)" << endl; }
};
你会看到 main()
的最后一行在上面的示例程序中会将其打印到标准输出:
A::operator , (string)
这意味着 B
,
的重载运算符不再隐藏 A
中定义的重载,这很可能是您想要的。
更新:
还有一个问题,答案还没有涵盖。 ,
的过载基类中的运算符 Fields
返回对 Fields
类型对象的引用.自 ,
运算符关联到左侧,表达式 e1, e2, e3
被评估为 (e1, e2), e3
.在您的具体情况下,(e1, e2)
的结果是对不支持 ,
重载的基类的引用派生类支持的运算符。
让我们再次将其简化为反射(reflect)您的设计的更简单示例:
#include <iostream>
#include <string>
using namespace std;
struct A
{
// Operator overloads return a reference to A
A& operator , (int)
{ cout << "A::operator , (int)" << endl; return *this; }
A& operator , (string)
{ cout << "A::operator , (string)" << endl; *this; }
};
struct B : A
{
// Imported overloads still return a reference to A
using A::operator ,;
// This overload returns a reference to B
B& operator , (double)
{ cout << "B::operator , (double)" << endl; return *this; }
};
int main()
{
B b;
b, 3.0;
b, "hello", 3.2; // What will be displayed here?
}
考虑示例的最后一行。您可能希望它调用 B::operator , (double)
, 但这是打印到标准输出的内容:
A::operator , (int)
为什么?好吧,因为逗号运算符的关联性和重载的返回类型。首先,表达式 b, "hello"
被评估,并返回一个 对 A
的引用
。然后,根据这个表达式的结果,函数 A::operator , (3.2)
将被调用。 A
有一个可行的功能,即接受 int
的功能.然后那个被选中。 B
因为第一个表达式的结果 b, "hello"
没有看到重载类型为 A&
.
那么怎么解决呢?您可以使用称为 CRTP(“Curiously Recurring Template Pattern”)的设计模式并转换 A
的定义和 B
进入以下内容:
template<typename T>
struct A
{
T& operator , (int)
{ cout << "A::operator , (int)" << endl; return *(static_cast<T*>(this)); }
T& operator , (string)
{ cout << "A::operator , (string)" << endl; *(static_cast<T*>(this)); }
};
struct B : A<B>
{
using A::operator ,;
B& operator , (double)
{ cout << "B::operator , (double)" << endl; return *this; }
};
这样,main()
的最后一行上面示例中的函数将打印您期望的标准输出:
A::operator , (string)
B::operator , (double)
关于c++ - 在专用模板中添加运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14564945/
我创建了一个用户可以添加测试的字段。这一切运行顺利我只希望当用户点击(添加另一个测试)然后上一个(添加另一个测试)删除并且这个显示在新字段中。 所有运行良好的唯一问题是点击(添加另一个字段)之前添加另
String[] option = {"Adlawan", "Angeles", "Arreza", "Benenoso", "Bermas", "Brebant
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我正在努力将 jQuery 滚动功能添加到 nav-tab (Bootstrap 3)。我希望用户能够选择他们想要的选项卡,并在选项卡内容中有一个可以平滑滚动到 anchor 的链接。这是我的代码,可
我正在尝试在用户登录后再添加 2 个 ui 选项卡。首先,我尝试做一个之后。 $('#slideshow').tabs('remove', '4'); $("#slideshow ul li:last
我有一个包含选择元素的表单,我想通过选择添加和删除其中一些元素。这是html代码(这里也有jsfiddle http://jsfiddle.net/txhajy2w/):
正在写这个: view.backgroundColor = UIColor.white.withAlphaComponent(0.9) 等同于: view.backgroundColor = UICo
好的,如果其中有任何信息,我想将这些列添加到一起。所以说我有 账户 1 2 3 . 有 4 个帐户空间,但只有 3 个帐户。我如何创建 java 脚本来添加它。 最佳答案 Live Example H
我想知道是否有一种有效的预制算法来确定一组数字的和/差是否可以等于不同的数字。示例: 5、8、10、2,使用 + 或 - 等于 9。5 - 8 = -3 + 10 = 7 + 2 = 9 如果有一个预
我似乎有一个卡住的 git repo。它卡在所有基本的添加、提交命令上,git push 返回所有内容为最新的。 从其他帖子我已经完成了 git gc 和 git fsck/ 我认为基本的调试步骤是
我的 Oracle SQL 查询如下- Q1- select hca.account_number, hca.attribute3, SUM(rcl.extended_amou
我正在阅读 http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingG
我正在尝试添加一个“加载更多”按钮并限制下面的结果,这样投资组合页面中就不会同时加载 1000 个内容,如下所示:http://typesetdesign.com/portfolio/ 我对 PHP
我遇到这个问题,我添加了 8 个文本框,它工作正常,但是当我添加更多文本框(如 16 个文本框)时,它不会添加最后一个文本框。有人遇到过这个问题吗?提前致谢。 Live Link: JAVASCRIP
add/remove clone first row default not delete 添加/删除克隆第一行默认不删除&并获取正确的SrNo(例如:添加3行并在看到问题后删除SrNo.2)
我编码this ,但删除按钮不起作用。我在控制台中没有任何错误.. var counter = 0; var dataList = document.getElementById('materi
我有一个类似数组的对象: [1:数组[10]、2:数组[2]、3:数组[2]、4:数组[2]、5:数组[3]、6:数组[1]] 我正在尝试删除前两个元素,执行一些操作,然后将它们再次插入到同一位置。
使用的 Delphi 版本:2007 你好, 我有一个 Tecord 数组 TInfo = Record Name : String; Price : Integer; end; var Info
我使用了基本的 gridster 代码,然后我声明了通过按钮添加和删除小部件的函数它工作正常但是当我将调整大小功能添加到上面的代码中时,它都不起作用(我的意思是调整大小,添加和删除小部件) 我的js代
title 323 323 323 title 323 323 323 title 323 323 323 JS $(document).keydown(function(e){
我是一名优秀的程序员,十分优秀!