Подтвердить что ты не робот

Ошибка вызова пользовательского оператора + на временном объекте при наличии дополнительных скобок

Если у меня есть пользовательский operator+(), как в:

    class A
    {
    public:
        A operator+(A)
        {
            return A();
        }
    };

Затем выполняется следующее:

    A a = A() + A();

но g++ - 4.7 выводит сообщение об ошибке:

    A a = (A()) + A();

В частности, сообщение об ошибке error: no match for ‘operator+’ in ‘+A()’.
Похоже, что в выражении (A()) игнорируется.

Мой вопрос: есть A a = (A()) + A();, который должен компилироваться, а если нет, то почему?

Примечание: это произошло со мной, когда я сделал #define X (Identity()), а затем попытался сделать X + X.

4b9b3361

Ответ 1

Это синтаксис литой.

Причиной этого является то, что литье и унарное сложение, вычитание и умножение (оператор разыменования) имеют более высокий приоритет, чем их двоичные копии. Поскольку здесь пробелы здесь не имеют значения, это также можно читать как:

    A a = (A()) +A();

Листинг и unary+ имеют более высокий приоритет, чем двоичный operator+, поэтому выражение принимает прежнее значение.

Возможно, вам будет интересно (как и я), как вы можете использовать, когда вещь внутри не является типом. Введите САМЫЙ VEXING PARSE!, что означает, что я пытаюсь передать объект типа +A() функции, принимающей 0 аргументов и возвращающей объект типа A.

Для записи синтаксис:

    A a = ((A())) + A();

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

Это также объясняет, почему проблема не возникает с оператором деления, а не с добавлением, у него нет унарной копии.