Я пытаюсь написать неинтрузивные подпрограммы boost :: serialization для вложенного класса с частным членом. К сожалению, я не могу убедить g ++ в том, что процедура сериализации является другом внутреннего класса. Кажется, g ++ требует прямого объявления процедуры сериализации, которая, в свою очередь, потребует прямого объявления вложенного класса, который, в свою очередь, не может быть выполнен на C++. Я что-то упустил или это просто невозможно? clang ++ в отличие от этого не требует прямого объявления и не имеет проблем с приведенным ниже кодом. Следующий код иллюстрирует проблему:Объявление друга в вложенных классах, требующих форвардного объявления
#include <boost/archive/text_oarchive.hpp>
class Outer;
//class Outer::Inner; // Not valid C++
namespace boost
{
namespace serialization
{
template <class Archive>
void serialize(Archive &ar, Outer& outer, const unsigned int version);
//template <class Archive>
//void serialize(Archive &ar, Outer::Inner& inner, const unsigned int version); // Cannot be done since forward declaration of nested class not possible.
}
}
class Outer
{
class Inner
{
int member_{42};
template <class Archive>
friend void boost::serialization::serialize(Archive &ar, Outer::Inner &inner, const unsigned int version); // This does not work with gcc since the compiler seems to expect a forward declaration, which cannot be done (see above).
};
Inner inner_;
template <class Archive>
friend void boost::serialization::serialize(Archive &ar, Outer &outer, const unsigned int version);
template <class Archive>
friend void boost::serialization::serialize(Archive &ar, Inner &inner, const unsigned int version);
};
namespace boost
{
namespace serialization
{
template <class Archive>
void serialize(Archive &ar, Outer& outer, const unsigned int version)
{
ar & outer.inner_;
}
template <class Archive>
void serialize(Archive &ar, Outer::Inner& inner, const unsigned int version)
{
ar & inner.member_;
}
}
}
int main()
{
Outer outer;
boost::archive::text_oarchive(std::cout) << outer;
}
Чтобы быть скомпилирован с -std=c++11
и -lboost_serialization
. Компиляция с g ++ жалуется, что member_
является закрытым, хотя присутствует декларация друга. Действительно ли g ++ отклоняет объявление друга во внутреннем классе?
Итак, вы говорите, что да g ++ - это право отказаться от кода, и да, это просто невозможно? – user1225999
"[...] ссылается на [...]" - так что clang ++ тоже не ошибается в принятии кода? Или это означает, что квалифицированное объявление _must_ относится к ранее объявленному члену пространства имен? – user1225999
@ user1225999 «должен» должно быть. Кланг ошибается. –