Const Reference для удлинения временного срока службы жизни

StackOverflow https://stackoverflow.com/questions/4086508

  •  28-09-2019
  •  | 
  •  

Вопрос

У меня есть вопрос о своем стандартном соблюдении C ++ или отсутствие этого.

В моем проекте я использую какой-то простой класс охранника, который использует Const Reference Trick. Я использую Visual Studio 2005, и есть две конфигурации - один для обычной сборки выпуска, а второй для модульных тестов.

В обоих случаях в конце есть некоторые временные висит на ссылке Const, но то, что происходит тем временем, это проблема. Для конфигурации выпуска эталонные точки Const непосредственно к TEMP, созданной в возвращении шаблона функции помощника, который создает экземпляр охрана (не вызывается конструктор копирования, даже не созданный для этого значения).

Но для модульного теста Conf Tempte шаблона функции сначала скопирован, а затем вызывается его деструктор, делая то, что должно быть сделано только после того, как эта ссылка на константу выходит из системы.

Я решил проблему, отключая исходную охрану в конструкторе копирования базового класса (поэтому действие в деструкуре не запускается для конфигурации, для которого называется Copy Construstor), но что мне беспокоит:

Является ли копией-временное поведение стандартным соответствительным? Соответствует ли стандарт, что ссылка на константу должна указывать непосредственно в TEMP или это поведение, определенное введению, не указано в стандарте?

Я основал свой код примерно на страховой статье охраны объема в статье GOTW 88 DDJ и Herb Sutter, но и эти источники, похоже, не принимают ранний призыв к деструктора.

Любая информация от кого-то более знания будет оценена.

РЕДАКТИРОВАТЬ:

ОК, код что-то подобное:

class GuardBase
{
public:

  GuardBase() : m_enabled(true)
  {}

  //this is done because in normal build no copy constructor is called ( directly using the function temporary)
  //but for UT conf somehow the original temp is copied and destroyed
  GuardBase(const GuardBase& other)
  {
    other.disable();
  }

  void disable() const
  {
    m_enabled = false;
  }

protected:
  //member is mutable because we will access the object through the const reference
  mutable bool m_enabled;
};

template< typename Arg, typename ObjType, typename MemberMethod >
class Guard1Arg : public GuardBase 
{
public:
  Guard1Arg(ObjType& obj, MemberMethod remover,  Arg arg) : m_arg(arg), m_remover(remover), m_object(obj)
  {}

  ~Guard1Arg()
  {
    if ( m_enabled )
    {
      (m_object.*m_remover)(m_arg);
    }
  }

private:
  Arg m_arg;
  MemberMethod m_remover;
  ObjType& m_object;

  //this class should not be assigned
  Guard1Arg& operator=(const Guard1Arg& other);

};

//utility template function used to create Guards using member functions with 1 argument
template<typename MemberFunction, typename Obj, typename Arg>
Guard1Arg<Arg, Obj, MemberFunction> MakeGuard1Arg(Obj& obj, MemberFunction memberFunction, Arg& arg)
{
  return Guard1Arg<Arg, Obj, MemberFunction>(obj, memberFunction, arg);
}


#define GUARD_CREATE(arg, remover) const GuardBase& guard = MakeGuard1Arg(*this,  remover, arg);
#define GUARD_DISABLE guard.disable();
#define GUARD_FRIEND template< typename Arg, typename ObjType, typename MemberMethod > friend class Guard1Arg;
Это было полезно?

Решение

Оба поведения являются стандартами, соответствующими. Если у вас есть код, как это:

T foo()
{
  return T();
}

int main()
{
  const T& x = foo();
}

Тогда концептуально, в foo, временный объект создан. Это временно скопировано на возврат ценности foo. Отказ В main, эта копия (которая также является временным объектом) обязана x.
Копия, которая является возвратным значением из foo Получает его срок службы, но не временный, который был источником для копирования.

Но стандарт C ++ явно позволяет вносить преимущественные временные объекты. Таким образом, вместо того, чтобы создавать временные и копирование в слот для возвратных значений, foo может напрямую создать временную в этом слоте.
Обе варианты возможны, и компилятор даже не должен документировать, когда он использует какой вариант.

Соответствующие разделы стандарта C ++ составляют 6,6,3 ([stmt.return]) и 12.2 ([Class.temporary]).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top