Возникла проблема с переносом проекта из одной реализации C++ в другую (из C++Builder5 на C++Builder6). Проблема заключается в следующем: в проекте интенсивно используется тип vector<TComInterface<Ixxxx> >; TComInterface — это смарт-указатель, у которого определен operator&; в C++Builder6 возникает ошибка компиляции, связанная с тем, что реализация vector-а (STLPort) для получения итераторов применяет operator& к элементам контейнера. В C++Builder5 использовалась другая реализация STL (от Rogue Wave), поэтому таких ошибок не возникало.
Вопросы, собственно, в следующем:
1. кто ошибся? автор STL, который не учёл возможность изменения семантики оператора & у элементов контейнера? Или ошибся я, создав непереносимый код?
2. как малой кровью решить мою проблему?
3. как без reinterpret_cast-ов взять адрес переменной, у типа которой определён operator&.
Здравствуйте, SuhanovSergey, Вы писали:
SS>Возникла проблема с переносом проекта из одной реализации C++ в другую (из C++Builder5 на C++Builder6). Проблема заключается в следующем: в проекте интенсивно используется тип vector<TComInterface<Ixxxx> >; TComInterface — это смарт-указатель, у которого определен operator&; в C++Builder6 возникает ошибка компиляции, связанная с тем, что реализация vector-а (STLPort) для получения итераторов применяет operator& к элементам контейнера. В C++Builder5 использовалась другая реализация STL (от Rogue Wave), поэтому таких ошибок не возникало.
SS>Вопросы, собственно, в следующем:
SS> 1. кто ошибся? автор STL, который не учёл возможность изменения семантики оператора & у элементов контейнера? Или ошибся я, создав непереносимый код?
Видимо, автор STL (пусть гуру меня поправят). От элементов контейнера требуется лишь copy-constructable and assignable и деструктор, не кидающий исключений.
SS> 2. как малой кровью решить мою проблему?
не отвечу
SS> 3. как без reinterpret_cast-ов взять адрес переменной, у типа которой определён operator&.
похоже, что только с reinterpret_cast<>.
См. <boost/utility/addressof.hpp>
template <typename T>
T* addressof(T& v)
{
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}
Здравствуйте, SuhanovSergey, Вы писали:
Смотри в MSDN CAdapt
... << RSDN@Home 1.1 alpha 1 >>
Здравствуйте, SuhanovSergey, Вы писали:
SS> 2. как малой кровью решить мою проблему?
Большой кровью можно так:
template<class Ixxx>
struct WrapPtr
{
typedef TComInterface<Ixxx> TPtr;
TPtr ptr_;
operator TPtr & () { return ptr_; }
operator TPtr const & () const { return ptr_; }
operator Ixxx * () const { return ptr_; }
// для in-параметров этого хватит,
// а для out-параметров - увы, только так: &(myvec[123].ptr_)
// или так: myvec[123].ppi()
Ixxx** ppi() { return &ptr_; }
Ixxx** ppv() { return (void**)ppi(); } // для всяческих QueryInterface, CoCreateInstance etc...
};