В настоящее время я работаю над проектом, в котором я использую:
- повысить библиотеки v1.39
- Eclipse CDT (Juno) и Cygwin
- Плагин CxxTest: http://wiki.web-cat.org/WCWiki/EclipsePlugins/CxxTestPlugin< /а>
и я столкнулся с проблемой, связанной с 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++. Мне все равно, будут ли эти проверки во время компиляции в моих тестах, я могу обойти это. Таким образом, любая помощь в любом из трех направлений будет очень полезна!
Отключение проверки 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
Отключение этого
const_cast_helper. Когда я запускаю свои тестовые программы (отличный от тестового проекта), мой код компилируется и работает, как и ожидалось, перегрузка const_cast создала проблемы.Реализация расширения, которое исправит эту ошибку. Я не знаю, нужно ли это делать в
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)) { }
Спасибо за ваш вклад заранее!