2012-05-03 1 views
2

Предположим, что у меня есть этот класс:Построить префикс оператора

class Int{ 
    private: 
     int x; 
    public: 
     Int(int i) : x(i) {} 
}; 

Могу ли я построить prefix + оператору написать выражение, x = + a b?

Я попытался перегрузить operator+ внутри класса, но компилятор жалуется, что operator+ должен быть унарным или двоичным, а не тройным.

Есть ли способ сделать такую ​​вещь?

+0

Что вы хотите '=' + означает? Как написано, это алгебраическая ерунда. –

+2

Нет, не стоит начинать писать Lisp на C++ (хотя мы и захотим). (По совпадению, 'x = + a' будет работать, но не' x = + a b'.) –

+0

@JohnDibling: Он описывает [Префиксная нотация] (http://en.wikipedia.org/wiki/Polish_notation). –

ответ

3

Вы не можете изменить способ интерпретации символа «+» компилятором - он имеет особое синтаксическое значение. Если вы готовы отказаться от символа +, вы можете создать класс с именем plus и перегрузить operator(), чтобы принять следующие аргументы.

По существу, вы создаете dsl, используя класс plus в качестве прокси-сервера для оператора +.

+0

О, может быть, у меня есть. Так что это невозможно из-за парсера? Если вы пишете '+ x x', нет никакого синтаксического правила, которое бы соответствовало. Правильно ли это (более или менее)? – Aslan986

+1

Да, все. – Matt

4

Нет, вы не можете изменить основной синтаксис выражения.

3

В общем, невозможно играть с основным синтаксисом C++, потому что он жестко связан с грамматикой. Но возможно

template<typename A, typename B> 
auto plus(const A& a, const B& b) -> decltype(a + b) { return a + b; } 
a = plus(a, b); 

подходит для замены? Построение этого для всех арифметических операторов тривиально.

2

Просто для удовольствия:

#include <iostream> 

struct Expr { 
    int value; 
    enum oper { plus = '+', minus = '-', times = '*', div = '/', nop = 0 } op; 
    Expr(int value, oper op) : value(value), op(op) { } 
    Expr(int value) : value(value), op(nop) {} 
    Expr operator+() { return Expr(value, plus); } 
    Expr operator-() { return Expr(value, minus); } 
    Expr operator*() { return Expr(value, times); } 
    Expr operator,(const Expr& rhs) { 
    Expr result(value, op); 
    switch(op) { 
     case '+': result.value += rhs.value; break; 
     case '-': result.value -= rhs.value; break; 
     case '*': result.value *= rhs.value; break; 
     case '/': result.value /= rhs.value; break; 
    } 
    return result; 
    } 
}; 

int main() { 
    Expr x(0), a(1), b(2); 
    x = (+ a , b); 
    std::cout << x.value << "\n"; 
} 
Смежные вопросы