Передача указателя на временный объект

Мы знаем, что можем передавать временные объекты функциям по константной ссылке, например:

class A
{
public:
    A(int _b = 0) 
    {
        b = _b;
    }

    int b;
};

void foo(A& a) {printf("%d", a.b);}
void cfoo(const A& a) {printf("%d", a.b);}

int main(void)
{
    //foo(A(4)); doesn't compile
    cfoo(A(5));
}

а как насчет перехода по указателю? почему это компилируется?

void pfoo(A* pa) {pa->b = 19;}

int main(void)
{
    pfoo(&A(5));
}

person Yaniv Far    schedule 18.09.2014    source источник
comment
Вы просто передаете указатель на переменную, созданную в стеке. Это просто адрес в памяти, который работает до тех пор, пока эта память действительна. Я не совсем понимаю, в чем проблема. Как вы думаете, почему должна работать ссылка, а не указатель?   -  person GlGuru    schedule 18.09.2014
comment
Не могли бы вы пожалуйста изменить слово анонимная переменная на временную. Думайте об этом как о способе (а) сэкономить на вводе текста и (б) точно описать фактическое состояние данных, которые передаются). И foo(A(5)) не может быть скомпилирован, потому что параметр decl является неконстантной ссылкой, и поэтому ему нельзя передать временную. Отправка адреса временного должна, по крайней мере, предупредить вас о том, что вы ошибались. Если этого не произошло, вам нужно запустить предупреждения компилятора или выбросить этот компилятор и получить тот, который предупредит вас о такой ужасности.   -  person WhozCraig    schedule 18.09.2014
comment
В gcc и clang error: taking address of temporary. Хотя может быть принудительно скомпилирован с -fpermissive и адрес даст ответ.   -  person alfC    schedule 18.09.2014
comment
@GlGuru &A(5) - это ошибка, это не указатель на переменную, созданную в стеке. Rvalue не может получить свой адрес.   -  person M.M    schedule 18.09.2014
comment
Спасибо, я поправился.   -  person GlGuru    schedule 18.09.2014
comment
Спасибо, я понимаю кое-что из того, что вы сказали, а кое-что нет. В любом случае, я предполагаю, что мой компилятор проглотил ошибку / предупреждение, и этот указатель передачи на временный объект неверен / не может быть выполнен.   -  person Yaniv Far    schedule 18.09.2014
comment
Возможный дубликат Передать временный объект функции, которая принимает указатель   -  person underscore_d    schedule 02.07.2017


Ответы (1)


а как насчет передачи указателя на анонимные переменные? почему это компилируется?

Вероятно, вы используете компилятор, который не поддерживает стандарт C ++.

Невозможно получить адрес (временного) объекта с r-значением. Это не должно компилироваться.


Однако operator& может быть перегружен, поэтому его можно будет вызвать для временного объекта, например:

struct A
{
    A* operator&() { return this; }
};

В C ++ 11 временный объект может быть привязан к ссылке на r-значение. После этого ссылка на r-значение ведет себя как l-значение и, следовательно, может быть взят адрес временного объекта:

struct A {};

void foo(A*);

void foo(A&& a) { foo(&a); }

int main() {
    foo(A{});
}
person Maxim Egorushkin    schedule 18.09.2014