Хорошо, чтобы обойти ограничения доступа, вы можете просто добавить другие экземпляры wrap
в друзья, поэтому добавьте template<typename U> friend class wrap;
где-нибудь в теле класса. Таким образом, ваш пример должен скомпилироваться.
Однако вам не следует так лгать компилятору. Вы передаете o
как const ref
, обещая не менять его, а затем в любом случае изменить. Это нехорошо (или разрешено стандартом), поэтому компилятор может свободно нарушать ваш код любым способом. Вы действительно должны использовать const_cast
для вызова функций, которые принимают аргументы как неконстантные, но которые не изменят сами аргументы (на ум приходит c apis). В этом случае я бы предложил объявить конструктор template<typename O> wrap(wrap<O>& o)
. Если вы действительно хотите принять это как постоянную ссылку, вы также можете пойти по пути объявления init
как mutable
, что означает, что его можно изменить, даже если объект const
Вы также должны заметить, что вы не объявляете конструктор копирования (хотя template<typename O> wrap( wrap<O> const & o )
может принять wrap<T>
, он не считается, так что вам нужно определить это тоже, иначе для копирования в тот же тип будет использоваться сгенерированный компилятором конструктор копирования.