Russian Qt Forum
Ноябрь 23, 2024, 22:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: checkFirstBase<>()  (Прочитано 4290 раз)
Akon
Гость
« : Сентябрь 13, 2010, 13:54 »

Данный шаблон функции нужен для проверки корректности, если используется downcast с помощью reinterpret_cast<>() (в целях оптимизации). 

Код:
/// Checks that \a BaseT is first base class of \a DerivedT. Another words, the function template
/// checks whether casting from \a DerivedT down to \a BaseT can be safety performed through
/// reinterpret_cast<>() (instead of static_cast<>()), i.e.:
/// reinterpret_cast<BaseT*>(derived) == static_cast<BaseT*>(derived);
/// Example:
/// \code
/// class C: public A, public B { ... }
/// checkFirstBase<A>(C); // OK
/// checkFirstBase<B>(C); // runtime error
/// \endcode
/// \warning The function template assumes that compiler places in memory base classes in order of
/// declaration. This is not a requarement of the C++ Standard.
template <typename BaseT, typename DerivedT>
inline void checkFirstBase()
{
DerivedT* const Derived = reinterpret_cast<DerivedT*>(1);
Q_UNUSED(Derived);
Q_ASSERT(reinterpret_cast<void*>(1) == reinterpret_cast<void*>(static_cast<BaseT*>(Derived))
&& "DerivedT does not coincide with BaseT (BaseT is not first base class of DerivedT)");
}

По логике, такая проверка может быть осуществлена в compile-time. Но сходу у меня это сделать не получилось Грустный
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #1 : Сентябрь 15, 2010, 00:26 »

Код:
<<<
/// checkFirstBase<A>(C); // OK
/// checkFirstBase<B>(C); // runtime error
>>>
/// checkFirstBase<A, C>(); // OK
/// checkFirstBase<B, C>(); // runtime error

Может привести к виду safe_reinterpret_cast<B>(a) как в остальных случаях?

Цитировать
По логике, такая проверка может быть осуществлена в compile-time. Но сходу у меня это сделать не получилось Грустный

boost::is_base_of что-то похожее, можно почерпнуть оттуда идею.
« Последнее редактирование: Сентябрь 15, 2010, 12:08 от navrocky » Записан

Гугль в помощь
Akon
Гость
« Ответ #2 : Сентябрь 15, 2010, 11:55 »

Цитировать
Может привести к виду safe_reinterpret_cast<B>(a) как в остальных случаях?
Да

Цитировать
boost::is_base_of что-то похожее, можно почерпнуть оттуда идею.
boost::type_traits мне не помог (мож чего проглядел).
boost::is_base_of в таких случаях, при downcast, всегда будет говорить "да". Важно установить, что при downcast'e к базовому классу численное значение указателя не изменится.
Код:
class A {...};
class B {...};
class C : public A, public B {...};

C c;

B* pb = &c;
C* pc = &c;

void* pb_value = reinterpret_cast<void*>(pb);
void* pc_value = reinterpret_cast<void*>(pc);

assert(pb == pc);  // не вопрос
assert(pb_value == pc_value);  // Опс

Т.е. в то время как сами указатели равны (pb == pc), их численные значения в общем случае не равны (pb_value != pc_value).
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #3 : Сентябрь 15, 2010, 12:11 »

Цитировать
boost::type_traits мне не помог (мож чего проглядел).
boost::is_base_of в таких случаях, при downcast, всегда будет говорить "да".
Я тоже ничего не нашел, но я имел ввиду что можно подсмотреть идею там и попытаться сделать свое.
Записан

Гугль в помощь
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 23.