В библиотеке 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 значительно упрощен, фильтр просто возвращает объект с 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.
а также
Если программа объявляет или определяет имя в контексте, где оно зарезервировано, за исключением случаев, явно разрешенных этим разделом, ее поведение не определено.
Других решений пока нет …