重载大于操作符的操作符将用户定义类型强制转换为原语,信息丢失
overloading greater than operator casts user-defined type to primitive, information is lost
在存在用户定义类型的c++库中,该类型将变量的符号值的文本表示添加到原始数据类型int, double,…bool:
template<typename T>
class Var {
T value;
//a datastructure containing Expressions and string representations of operators
Expression expr;
}
覆盖addition (+)
的操作符:
#define OVERLOAD_ARITHMETIC_OPERATOR(op, opName)
template<typename X, typename Y>
auto operator op(const X x, const Y y) ->
se::Var<decltype(__filter(x).getValue() op __filter(y).getValue())>
{
const auto __x = __filter(x);
const auto __y = __filter(y);
auto result = se::constructVar(__x.getValue() op __y.getValue());
if(__x.isSymbolic() || __y.isSymbolic()) {
result.setExpression(BINARY_EXPRESSION(opName, __x.getExpression(), __y.getExpression()));
}
return result;
}
OVERLOAD_ARITHMETIC_OPERATOR(+, ADD)
下面的程序:
main.cpp:
#define double Double
#define int Int
#define float Float
#define bool Bool
#include "aprogram.c"
#undef double
#undef int
#undef float
#undef bool
int main(){
std::cout << afunction();
}
aprogram.c:
int afunction(){
double t1 = ... ;
double t2 = ... ;
return t1 + t2;
}
返回t1.expr + t2.expr
。
当重载操作符greater (>)
时:
#define OVERLOAD_COND_OPERATOR(op, opName)
template<typename X, typename Y>
se::Var<bool> operator op(const X x, const Y y)
{
const auto __x = __filter(x);
const auto __y = __filter(y);
auto result = se::constructVar(__x.getValue() op __y.getValue());
if(__x.isSymbolic() || __y.isSymbolic())
result.setExpression(BINARY_EXPRESSION(opName, __x.getExpression(), __y.getExpression()));
return result;
}
OVERLOAD_COND_OPERATOR(>, GREATER)
并将函数()中的返回值更改为return t1 > t2
,我们期望得到类似的结果,t1.expr > t2.expr
,但结果被强制转换为bool类型,并且存储在Var.expr中的信息丢失。
虽然我相信+
和>
的操作符写得相似,你能帮我理解为什么>
的行为不同吗?你能帮我找到通缉的行为吗?
请反馈我的问题:帮我帮你帮我。
发布后添加的信息
1/__filter()
是一个返回数据结构Var的方法。在我的例子中Var被大大简化了,filter只返回包含T value
和Expression expr
的对象。
2/
typedef se::Var<double> Double;
typedef se::Var<int> Int;
typedef se::Var<char> Char;
typedef se::Var<float> Float;
typedef se::Var<bool> Bool;
你的程序将会做很多意想不到的事情,因为它有未定义的行为。
这是不允许的:
#define double Double
#define int Int
#define float Float
#define bool Bool
宏名必须是标识符,这些是关键字,而不是标识符。
第17.6.4.3节讲得很清楚:
翻译单元的
#define
或#undef
名称在词法上不能与关键字、表3中列出的标识符或7.6中描述的属性令牌相同。
和
如果程序在保留名称的上下文中声明或定义了该名称,则该程序的行为是未定义的。
相关文章:
- 如何使用 C++ 中的原语初始化类(如 std::字符串从 const char* 初始化)
- 出于什么目的,可能需要从Boost库中同步原语和容器
- 使用 c++11 的并发原语是否有一个体面的wait_any实现?
- 如何使用编译时常量原语的类型
- 从 JNI 中的原语获取数字的简单方法
- 如何在 Windows 上仅使用事件和联锁原语实现递归锁
- 库在C/C++和其他语言中重现Java原语hashCode逻辑
- 提升::精神(经典)原语与自定义解析器
- 如何从更基本的同步原语中创建多读/单写锁
- boost::asio:"strand"类型的同步原语有什么名称吗?
- Qt同步原语可以与非QThread线程一起使用吗
- std::vector<> 使用 resize() 派生,它不初始化原语和转发construct_back
- 数据结构的线程安全性,在哪里添加同步原语
- 我可以将哪些同步原语与克隆(2)(C/C++)一起使用
- 在使用jni时,如何清理jfloat等原语?
- 使用cgal创建参数化的3D原语
- 按值传递原语
- 将我转换的.obj文件转换为OpenGL原语
- 二元操作符重载原语的字符串类
- 重载大于操作符的操作符将用户定义类型强制转换为原语,信息丢失