Тьфу, старайся никогда не использовать препроцессор для реального кода.Это почти всегда очень плохая идея.
Я реструктурировал макрос как шаблонную функцию.Я повеселился с типами decltypes, так что я вытащил класс черт, чтобы уменьшить сложность определения функции!
Я не вижу способа полностью избавиться от макросапросто для здравомыслия в декларации фактических перегрузок операторов.Теперь, однако, это всего лишь простой переход к шаблонной функции operator_impl (), и в этом вы сможете использовать #ifdefs для своего кода отладки.
template <typename T, typename U, typename Op>
struct op_result
{
typedef vector<decltype( (*((Op*)nullptr)) (*(T*)nullptr, *(U*)nullptr) ) > type;
};
template <typename T, typename U, typename Op>
inline typename op_result<T, U, Op>::type
operator_impl(const vector<T>& A, const vector<U>& B, Op op)
{
op_result<T, U, Op>::type C;
C.reserve(A.size());
typename vector<T>::const_iterator a = A.begin();
typename vector<U>::const_iterator b = B.begin();
while (a!=A.end())
{
C.push_back(op(*a, *b));
++a; ++b;
}
return C;
}
#define BINARY_VECTOR_RETURN_OPERATOR(optype) \
template <class T, class U> \
inline vector<decltype( *(const T*)nullptr optype *(const U*)nullptr)> \
operator optype (const vector<T>& A, const vector<U>& B) \
{ \
return operator_impl(A, B, [](const T& t, const U& u) {return t optype u;}); \
}