У меня есть вопрос о соблюдении стандартного стандарта C++ или его отсутствии.константа для временного удлинения срока службы
В моем проекте я использую простой класс Guard, который использует трюк const const. Я использую Visual Studio 2005 и есть две конфигурации - одна для обычной сборки релиза, а вторая для модульных тестов.
В обоих случаях в конце есть некоторое временное зависание ссылки на const, но то, что происходит в это время, является проблемой. Для конфигурации релиза ссылка const ссылается непосредственно на temp, созданный при возврате шаблона вспомогательной функции, который создает экземпляр Guard (никакой конструктор копирования не вызывается, даже не созданный для этого).
Но для тестирования устройства conf шаблон функции temp сначала копируется, а затем вызывается его деструктор, делая то, что должно быть сделано только после того, как ссылка на const перестает быть видимой.
Я решил эту проблему путем отключения оригинального охранника в базовой копии класса конструктора (так что действие в деструктор не вызывается для конфигурации, для которых конструктор копирования называется), но то, что беспокоит меня:
ли совместимость с копией по времени стандартная? Указывает ли стандарт, что ссылка const должна указывать непосредственно на temp, или это поведение, определяемое реализацией, не указано в стандарте?
Я основываю свой код примерно на предметной статье Scope Guard в статье DDJ и Herb Sutter's 88, но оба этих источника, похоже, не учитывают более ранний вызов деструктора.
Любая информация от кого-то более знающего будет оценена по достоинству.
EDIT:
Ok код что-то вроде этого:
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;
Есть код для иллюстрации? – sharptooth
Без кода невозможно точно сказать. Все ответы будут догадками. –