Я пытаюсь написать оболочку интеллектуального указателя (содержит boost shared_ptr или scoped_ptr или другую оболочку интеллектуального указателя); каждый тип обертки вводит немного дополнительной функциональности (например, использование журналов, ленивый init, проверка правильного порядка построения/уничтожения и т. д.), но я хочу, чтобы они были максимально невидимыми для пользователя (чтобы я мог обмениваться обертками просто изменив один typedef и, возможно, некоторый код конструктора, но ни один из кода использования).Обертка интеллектуальных указателей с заменой метода
Нормального использование тривиально:
template<typename T>
class some_smart_ptr_wrapper
{
public:
typedef typename T::value_type value_type;
...
value_type* get() { /*do something magic*/ return m_ptr.get(); }
const value_type* get() const { /*do something magic*/ return m_ptr.get(); }
// repeat for operator->, operator*, and other desired methods
private:
T m_ptr;
};
typedef some_smart_ptr_wrapper< boost::shared_ptr<int> > smart_int;
smart_int p;
(Теперь другой код можно использовать p
неотличим от shared_ptr, по крайней мере, для определенных операций, и я могу добавить дополнительные упаковщик, просто изменив ЬурейиЙ.)
Несколько оберток можно использовать одновременно, просто вложив их, как вы ожидали, и только код, который объявляет (а иногда и инициализирует) переменную, должен заботиться.
Иногда полезно иметь «базовый» общий/scoped_ptr из обертки (в частности, передать shared_ptr в качестве аргумента функции, которая не требует активации функциональности, добавленной оболочками); для одного слоя оберточной легко:
T& getPtr() { return m_ptr; }
const T& getPtr() const { return m_ptr; }
Но это не масштабируется хорошо для нескольких слоев обертки (абонент должен сделать p.getPtr().getPtr().getPtr()
правильное число раз).
То, что я хотел бы быть в состоянии сделать это объявить getPtr() таким образом, что:
- если T реализует getPtr(), то она возвращает m_ptr.getPtr() (независимо от типа, который) ,
- если T не реализует getPtr(), то он возвращает m_ptr.
- он по-прежнему доступен как в созвездиях, так и в неконтактных ароматах, как и следовало ожидать.
Конечным результатом является то, что один вызов getPtr() из внешнего кода «поднимет» цепочку к исходному интеллектуальному указателю, поскольку это будет единственный, который не реализует getPtr().
Я уверен, что решение будет включать SFINAE и boost :: enable_if; У меня была небольшая игра, пытаясь заставить что-то подобное работать, но до сих пор не повезло.
Решения или полностью альтернативные подходы как приветствуются; обратите внимание, что я хотел бы, чтобы он работал как в VC++ 2008, так и в GCC (т. е. C++ 11, к сожалению).
'value_type' должен быть' element_type', и вы должны иметь только один элемент 'get':' element_type * get() const; '. Указатель const не означает, что pointee является const. –
Справедливые точки. Благодарю. – Miral