Ошибки, баги, вопросы - страница 2199

Vladimir Karputov:
Что снова с форумом? Начался день и начались нереальные тормоза. Страницы грузятся то быстро, то в течении секунд 30.
ркн, наверное... с пушами наблюдается проблемы на др сервисах.. вроде как телеграм работает через них..
Ошибка компилятора
class A
{
public:
  int i;
  
  void f() const
  {
    A* Tmp = true ? &this : &this; // no problem - BUG!
//    A* Tmp = &this; // '=' - cannot convert from const pointer to nonconst pointer
    
    Tmp.i = 4;
  }
};

void OnStart()
{
  const A a;
  
  a.f();
  
  Print(a.i); // 4
}
Ilnur Khasanov:
ркн, наверное... с пушами наблюдается проблемы на др сервисах.. вроде как телеграм работает через них..

Нахожусь вне России, сайт все равно иногда подвисает. Но у меня так не один месяц. Привык.

fxsaber:

Спасибо! Получается, что return объекта и "=" при определении объекта идут через доп. конструктор.

Хотелось бы на самом деле наглядную таблицу где-то посмотреть, в каких случаях идут вызовы конструкторов (и каких), а в каких - операторов. Сейчас все на уровне интуиции, а она сбоит, конечно.

Вы лучше не очень то расчитывайте на какие-то конкретные правила, компиляторам разрешено весьма вольно оптимизировать такие вещи (rvo, nrvo, copy elision, может ещё какие оптимизации спокойно вырежут лишнее). Копирующий конструктор и оператор "равно" должны делать одни и те же действия (не нужно закладывать в них разное поведение). Есть один хороший подход, называется "copy-and-swap idiom", если позволяет английский, то тут детально описано https://stackoverflow.com/questioncopy-and-swap idioms/3279543/what-is-the-copy-and-swap-idiom.
Если коротко, то пишется одна swap  функция, которая используется во всех конструкторах и операторах (мы уменьшаем количество кода, и получаем одинаковое поведение в результате чего не паримся о том, что там компилятор вызовет, вырежет, заоптимизирует).

dumb_array& operator=(dumb_array other)
{
    swap(*this, other);
    return *this;
}
dumb_array (dumb_array &&other)
{//this должен быть в валидном состоянии
    swap(*this, other);
}
dumb_array& operator=(dumb_array &&other)
{
    swap(*this, other);
    return *this;
}

"Выделенные строки вызывают вопросы. Почему временные объекты не грохнулись сразу, как были использованы? Т.е. до вывода тридцати. " 

Правильно вызывают вопросы, думаю. Временные объекты должны были разрушиться после двоеточия.

ЗЫ: я там код немного подправил, т.к. копирующий конструктор (не перемещающий) нужен в любом случае. Для мкл выгода не столь очевидна из-за отсутствия rvalue ссылок.
What is the copy-and-swap idiom?
What is the copy-and-swap idiom?
  • stackoverflow.com
What is this idiom and when should it be used? Which problems does it solve? Does the idiom change when C++11 is used? Although it's been mentioned in many places, we didn't have any singular "what is it" question and answer, so here it is. Here is a partial list of places where it was previously mentioned:
pavlick_:

Вы лучше не очень то расчитывайте на какие-то конкретные правила, компиляторам разрешено весьма вольно оптимизировать такие вещи (rvo, nrvo, copy elision, может ещё какие оптимизации спокойно вырежут лишнее). Копирующий конструктор и оператор "равно" должны делать одни и те же действия (не нужно закладывать в них разное поведение). Есть один хороший подход, называется "copy-and-swap idiom", если позволяет английский, то тут детально описано https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom.
Если коротко, то пишется одна swap  функция, которая используется во всех конструкторах и операторах (мы уменьшаем количество кода, и получаем одинаковое поведение в результате чего не паримся о том, что там компилятор вызовет, вырежет, заоптимизирует).

"Выделенные строки вызывают вопросы. Почему временные объекты не грохнулись сразу, как были использованы? Т.е. до вывода тридцати. " 

Правильно вызывают вопросы, думаю. Временные объекты должны были разрушиться после двоеточия.

Спасибо, в СД уже предупредили о планах по RVO.

Почему скрипт ничего не выводит?
class A
{
public:
  A() {}
  
  template <typename T>
  void operator =( T& )
  {
    Print(__FUNCSIG__);
  }

  template <typename T>
  A( T& )
  {
    Print(__FUNCSIG__);
  }
};

A* f()
{
  return(new A);
}

void OnStart()
{
  A* a = f();
  
  A* b;
  b = f();
  
  delete a;
  delete b;
}

Что это значит?

2018.04.24 14:02:21.721 Books   invalid book item[Si-6.18,buy,61996.00000,-50]
fxsaber:
Почему скрипт ничего не выводит?
потому что передача указателя а не по значению
Комбинатор:
потому что передача указателя а не по значению

Что-то совсем перестал понимать. Вот код

class A
{
public:
  template <typename T>
  void operator =( T& ) // Без ссылки работает
  {
    Print(__FUNCSIG__);
  }
  
  void operator =( int )
  {
    Print(__FUNCSIG__);
  }
};

void f( A*& )
{
  Print(__FUNCSIG__);
}

void OnStart()
{
  A* a = new A;  
  
  A b;  
  b = a; // cannot convert type ' *' to reference of type 'A *'
  
  a = a;
  a = 1;
  
  f(a);
  
  delete a;
}

Почему-то ругается на передачу указателя по ссылке. При этом функция f спокойно по ссылке принимает указатель.


Результат

void A::operator=<A*>(A*)
void A::operator=(int)
void f(A*&)

Оператор с int-ом вызвался без проблем, а оператор с указателем - нет.

Без ссылки по логике тоже не должен работать (имхо). это возможно особенность mql указателей - то что их разыменовывать не надо