Здравствуйте, _nn_, Вы писали:
__>В C++11 можно было бы просто сделать __>
__>auto const& lockScope = LockScope(cs);
__>
__>И тогда у lockScope был бы конкретный тип.
__>А как можно это решить в рамках C++03 ?
Я не вижу тут решения без магии. Да и с магией, если хочется использовать только языковые средства.
Если можно припудрить макросом, то вот решение в лоб:
template<typename T>
ConcreteScopeLocker<T> LockScope(T& lock)
{
return ConcreteScopeLocker<T>(lock);
}
#define CreateLockScope(m, v) \
const ConcreteScopeLocker<T> & v = LockScope(m)
int main()
{
{
MyLock ml;
CreateLockScope(m1, lockScope); // Не нужно указывать конкретный тип переменнойint i = 1;
puts("Inside block");
lockScope.Unlock();
lockScope.Lock();
}
return 0;
}
Недостатки очевидны: использование препроцессора и замыливание создания lockScope (эту проблему, впрочем, легко решить немного изменив дизайн).
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, _nn_, Вы писали:
__>>Пишу код для блокировок. __>>Придумался такой механизм:
U>вообще не ясно к чему такие заморочки U>Lock\Unlock по семантике должны быть неконстантными
Здравствуйте, _nn_, Вы писали:
__>Пишу код для блокировок.
__>Однако Lock/Unlock пришлось сделать виртуальными. __>В C++11 можно было бы просто сделать __>
__>auto const& lockScope = LockScope(cs);
__>
__>И тогда у lockScope был бы конкретный тип.
__>А как можно это решить в рамках C++03 ?
__>P.S. __>Желательно без BOOST_TYPEOF
Возможно нужен p-impl и универсальный ScopeLocker?
Здравствуйте, _nn_, Вы писали:
__>Пишу код для блокировок. __>Придумался такой механизм:
__>...
__>И тогда у lockScope был бы конкретный тип.
__>А как можно это решить в рамках C++03 ?
__>P.S. __>Желательно без BOOST_TYPEOF
Здравствуйте, Warturtle, Вы писали:
W>Здравствуйте, _nn_, Вы писали:
__>>Пишу код для блокировок. __>>Придумался такой механизм:
__>>...
__>>И тогда у lockScope был бы конкретный тип.
__>>А как можно это решить в рамках C++03 ?
__>>P.S. __>>Желательно без BOOST_TYPEOF
W>Можно, например, на манер этого
Здравствуйте, Alex Dav, Вы писали:
AD>просто для повышения моих знаний — расскажите плиз зачем это надо. AD>Спасибо.
Просто так избавляться не обязательно.
Это оптимизация, к которой нужно подходить внимательно.
( Если конечно виртуальная функция используется не по делу и тогда это пессимизация )
Без виртуальной функции компилятор сможет соптимизировать вызов и даже заинлайнить код.
С виртуальной функцией вероятность этого гораздо ниже.
Кроме того в некоторых контекстах нельзя использовать виртуальные функции вообще из-за невозможности контроля над таблицой виртуальных функций.
Здравствуйте, _nn_, Вы писали:
__>Пишу код для блокировок. __>Придумался такой механизм: __>...
__>Однако Lock/Unlock пришлось сделать виртуальными. __>В C++11 можно было бы просто сделать __>
__>auto const& lockScope = LockScope(cs);
__>
__>И тогда у lockScope был бы конкретный тип.
__>А как можно это решить в рамках C++03 ?
__>P.S. __>Желательно без BOOST_TYPEOF
По-моему, все можно упростить. Схематично так (не компилировал):
Здравствуйте, Alexander G, Вы писали:
AG>Плохой механизм, если ConcreteScopeLocker коснтруктор копий будет вызван, анлоков будет больше чем локов. AG>http://codepad.org/ntHR4daV
Знаем. Это лечится через move constructor или его аналога
Здравствуйте, _nn_, Вы писали:
__>Знаем. Это лечится через move constructor или его аналога
сам по себе временный анлок тоже подозрительно выглядит, при исключении во впремя временного анлока опять же будут два анлока.
я вообще думаю, что в обычном юз кейсе для лока не нужно вызывать .Unlock и .Lock .
в конструкторе/деструкторе же вызовы и так невиртуальны (если компилятор не додумается их сделать невиртуальными, ему можно помочь.
__>Однако Lock/Unlock пришлось сделать виртуальными. __>В C++11 можно было бы просто сделать __>
__>auto const& lockScope = LockScope(cs);
__>
__>И тогда у lockScope был бы конкретный тип.
__>А как можно это решить в рамках C++03 ?
В поставленном ключе, на мой взгляд, задача легальным способом силами С++ 03 не решается. Все сводится к необходимости изобрести свой TYPEOF. Что обычно имеет тенденцию не работать на различных полуэкзотических компиляторах.
Лучше сделать как в бусте. Тайпдефом — LockObject::ScopedLock.
На первый взгляд это выглядит не сильно лучше ScopedLock<LockObject>, но на деле позволяет писать трейты, не задумываясь о пригодности ScopedLock для данного объекта.