Кастинг проблем с BOOST_FOREACH и плагином cxxtest

В настоящее время я работаю над проектом, в котором я использую:

и я столкнулся с проблемой, связанной с const_cast. Я искал повсюду и не нашел источников в Интернете, которые могли бы мне помочь. Проблема возникает, когда я вызываю BOOST_FOREACH в тестовом методе. Я продолжаю получать следующую ошибку:

/usr/include/boost/foreach.hpp: In member function 
'boost::foreach_detail_::rvalue_probe<T>::operator T&() const [with T = 
boost::unordered_map<std::basic_string<char>, std::basic_string<char> >]':

...   instantiated from here /usr/include/boost/foreach.hpp:476:90: 
error: invalid cast from type 
Dereferee::const_cast_helper<boost::foreach_detail_::rvalue_probe<boost::unordered_map<std
::basic_string<char>, std::basic_string<char> > >*> 
to type 'boost::unordered_map<std::basic_string<char>, std::basic_string<char> >*

const_cast_helper

Я начал разбирать проблему и обнаружил, что оператор const_cast перегружен с целью какой-то проверки во время выполнения, не знаю чего. В общем, есть Dereferee::const_cast_helper, являющийся частью зависимостей cxxtest, перегрузка оператора const_cast.

Этот помощник отменяет определение оператора const_cast (!)

#ifdef const_cast
#undef const_cast
#endif

и в конце повторно вводит оператор const_cast:

#define const_cast ::Dereferee::const_cast_helper

так что каждый раз, когда вызывается const_cast, вызывается соответствующий конструктор этого помощника. Конструкторы принимают указатели, ссылки, константные указатели и константные ссылки.

Источник находится здесь: https://github.com/web-cat/dereferee-with-cxxtest/blob/master/Dereferee/include/dereferee/const_cast.h

rvalue_probe

Boost также играет с приведениями, чтобы увидеть, является ли итерируемая коллекция lvalue или rvalue, чтобы избежать ее копирования/пересчета выражения.

Компилятор жалуется на следующее:

template<typename T>
struct rvalue_probe
{
    ...
    operator T &() const { return *reinterpret_cast<T *>(const_cast<rvalue_probe *>(this)); }
};

В моем случае T - это boost::unordered_map, и каким-то образом комбинация этого приведения и перегрузки помощника ломается...

Пути решения?

Я изучил, какими могут быть возможные решения, но я не знаю, как их реализовать, у меня нет такого большого опыта работы с C++. Мне все равно, будут ли эти проверки во время компиляции в моих тестах, я могу обойти это. Таким образом, любая помощь в любом из трех направлений будет очень полезна!

  1. Отключение проверки rvalue boost, игра с BOOST_WORKAROUND и литералами, определенными в foreach.hpp

    BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION BOOST_FOREACH_NO_RVALUE_DETECTION BOOST_FOREACH_NO_CONST_RVALUE_DETECTION BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION

  2. Отключение этого const_cast_helper. Когда я запускаю свои тестовые программы (отличный от тестового проекта), мой код компилируется и работает, как и ожидалось, перегрузка const_cast создала проблемы.

  3. Реализация расширения, которое исправит эту ошибку. Я не знаю, нужно ли это делать в const_cast_helper или rvalue_probe, но это не принесло никакой пользы.

template <typename T> const_cast_helper(rvalue_probe<U>* value_to_cast) : cast_value(const_cast<U*>(value_to_cast)) { }

Спасибо за ваш вклад заранее!


person Matija Lukic    schedule 09.08.2013    source источник


Ответы (1)


После еще нескольких копаний мне удалось найти обходной путь. Я определил символ DEREFEREE_NO_CONST_CAST для моей конфигурации сборки. Это предотвратило компиляцию const_cast_helper. Надеюсь, багов не будет, тесты уже идут...

person Matija Lukic    schedule 09.08.2013