Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何避免容器的序列化程序和序列化程序之间的循环模板依赖关系?_C++_Templates_Serialization_Stl_Circular Dependency - Fatal编程技术网

C++ 如何避免容器的序列化程序和序列化程序之间的循环模板依赖关系?

C++ 如何避免容器的序列化程序和序列化程序之间的循环模板依赖关系?,c++,templates,serialization,stl,circular-dependency,C++,Templates,Serialization,Stl,Circular Dependency,我正在为stl容器的反序列化编写模板类 假设我想序列化一个集。我有一个基本序列化类和以下模板: template<typename T>class serialiser; template<>class serialiser<int>:public serialisation<int>{ public: void serialise ( int t ); }; 这仅适用于元素本身不包含容器的容器。 问题 如果要序列化映射,该怎么办 由于每个

我正在为stl容器的反序列化编写模板类

假设我想序列化一个
。我有一个基本
序列化
类和以下模板:

template<typename T>class serialiser;

template<>class serialiser<int>:public serialisation<int>{
public:
  void serialise ( int t );
};
这仅适用于元素本身不包含容器的容器。

问题 如果要序列化
映射
,该怎么办

由于每个元素的类型都是成对的,因此我需要以下类:

template<>class serialiser<pair<int,set<int> > >:public serialisation<pair<int,set<int> > >{
public:
  void serialise ( const pair<int,set<int> >t );
private:
  serialiser<int>t_first_serialiser;

  /* Notice that I must declare a Container_serialiser.
   */
  Container_serialiser<set<int> >t_second_serialiser;
};
问题代码 (我必须承认我忘记了这个问题。)

多亏了@michael gopshtein的评论,我最终偶然发现了它,它很好地解决了这个问题。注意,我必须同时使用
模板类Serialiser
模板内联void serialise(const SerialisedType&x)
。函数本身不能部分专门化,但大多数
Serialiser::serialise
的专门化依赖于对
::serialise
的常规调用

要序列化
std::map
,我将编写以下代码:

#include <map>
#include <set>
#include <utility>

// For the sake of having a MWE, I'll just write int-s to stdout.
#include <iostream>

template <typename SerialisedType> class Serialiser;

template <typename SerialisedType>
inline void serialise(const SerialisedType &x) {
  Serialiser<SerialisedType>::serialise(x);
}

template <> class Serialiser<int> {
public:
  inline static void serialise(const int &x);
};

template <typename Key> class Serialiser<std::set<Key>> {
public:
  inline static void serialise(const std::set<Key> &x);
};

template <typename T1, typename T2> class Serialiser<std::pair<T1, T2>> {
public:
  inline static void serialise(const std::pair<T1, T2> &x);
};

template <typename Key, typename T>
class Serialiser<std::map<Key, T>> {
public:
  inline static void serialise(const std::map<Key, T> &x);
};

void Serialiser<int>::serialise(const int &x) {
  std::cout << x << "\n";
}

template <typename Key>
void Serialiser<std::set<Key>>::serialise(const std::set<Key> &x) {
  {
    const typename std::set<Key>::const_iterator x_cend = x.cend();

    for (typename std::set<Key>::const_iterator x_iterator = x.cbegin();
         x_iterator != x_cend; ++x_iterator)
      ::serialise(*x_iterator);
  }
}

template <typename T1, typename T2>
void Serialiser<std::pair<T1, T2>>::serialise(const std::pair<T1, T2> &x) {
  ::serialise(x.first);
  ::serialise(x.second);
}

template <typename Key, typename T>
void Serialiser<std::map<Key, T>>::serialise(const std::map<Key, T> &x) {
  {
    const typename std::map<Key, T>::const_iterator x_cend = x.cend();

    for (typename std::map<Key, T>::const_iterator x_iterator = x.cbegin();
         x_iterator != x_cend; ++x_iterator)
      ::serialise(*x_iterator);
  }
}

int main() {
  std::map<int, std::set<int>> u {
    {5, {2, 3}},
    {7, {2, 3}}
  };
  serialise(u);
}
(我必须承认我忘记了这个问题。)

多亏了@michael gopshtein的评论,我最终偶然发现了它,它很好地解决了这个问题。注意,我必须同时使用
模板类Serialiser
模板内联void serialise(const SerialisedType&x)
。函数本身不能部分专门化,但大多数
Serialiser::serialise
的专门化依赖于对
::serialise
的常规调用

要序列化
std::map
,我将编写以下代码:

#include <map>
#include <set>
#include <utility>

// For the sake of having a MWE, I'll just write int-s to stdout.
#include <iostream>

template <typename SerialisedType> class Serialiser;

template <typename SerialisedType>
inline void serialise(const SerialisedType &x) {
  Serialiser<SerialisedType>::serialise(x);
}

template <> class Serialiser<int> {
public:
  inline static void serialise(const int &x);
};

template <typename Key> class Serialiser<std::set<Key>> {
public:
  inline static void serialise(const std::set<Key> &x);
};

template <typename T1, typename T2> class Serialiser<std::pair<T1, T2>> {
public:
  inline static void serialise(const std::pair<T1, T2> &x);
};

template <typename Key, typename T>
class Serialiser<std::map<Key, T>> {
public:
  inline static void serialise(const std::map<Key, T> &x);
};

void Serialiser<int>::serialise(const int &x) {
  std::cout << x << "\n";
}

template <typename Key>
void Serialiser<std::set<Key>>::serialise(const std::set<Key> &x) {
  {
    const typename std::set<Key>::const_iterator x_cend = x.cend();

    for (typename std::set<Key>::const_iterator x_iterator = x.cbegin();
         x_iterator != x_cend; ++x_iterator)
      ::serialise(*x_iterator);
  }
}

template <typename T1, typename T2>
void Serialiser<std::pair<T1, T2>>::serialise(const std::pair<T1, T2> &x) {
  ::serialise(x.first);
  ::serialise(x.second);
}

template <typename Key, typename T>
void Serialiser<std::map<Key, T>>::serialise(const std::map<Key, T> &x) {
  {
    const typename std::map<Key, T>::const_iterator x_cend = x.cend();

    for (typename std::map<Key, T>::const_iterator x_iterator = x.cbegin();
         x_iterator != x_cend; ++x_iterator)
      ::serialise(*x_iterator);
  }
}

int main() {
  std::map<int, std::set<int>> u {
    {5, {2, 3}},
    {7, {2, 3}}
  };
  serialise(u);
}

难道你不能避免定义
容器\u serialiser
,让所有的类都成为
serialiser
的专用类吗?对每种容器类型都有单独的专门化?在这种情况下,您可以定义
序列化器
序列化器
序列化器
等。您不能避免定义
容器\u序列化器
,并使所有类都成为
序列化器
的专用类吗?对每种容器类型都有单独的专门化?在这种情况下,您可以定义
序列化程序
序列化程序
序列化程序
等。
#include <iostream>
#include <map>
#include <set>
#include <utility>

using std :: cout;

using std :: map;

using std :: set;

using std :: make_pair;
using std :: pair;

template<typename T>class serialisation{
public:
  virtual ~serialisation ( );
protected:
  virtual void serialise ( const T t ) = 0;
};

template<typename T>serialisation<T> :: ~serialisation ( ){
}

template<typename T>class serialiser;

template<>class serialiser<int>:public serialisation<int>{
public:
  void serialise ( const int t );
};

void serialiser<int>:: serialise ( const int t ){
  cout << t << '\n';
}

template<typename T>class Container_serialiser:public serialisation<T>{
public:
  void serialise ( const T t );
private:
  serialiser<typename T :: value_type>value_serialiser;
};

template<typename T>void Container_serialiser<T>:: serialise ( const T t ){
  for(typename T :: const_iterator t_iterator = t . begin ( );t_iterator != t . end ( );++ t_iterator){
    value_serialiser . serialise ( * t_iterator );
  }
}

template<>class serialiser<pair<int,set<int> > >:public serialisation<pair<int,set<int> > >{
public:
  void serialise ( const pair<int,set<int> >t );
private:
  serialiser<int>t_first_serialiser;

  Container_serialiser<set<int> >t_second_serialiser;
};

void serialiser<pair<int,set<int> > >:: serialise ( const pair<int,set<int> >t ){
  t_first_serialiser . serialise ( t . first );
  t_second_serialiser . serialise ( t . second );
}

int main ( ){
  set<int>t;
  t . insert ( 2 );
  t . insert ( 3 );
  Container_serialiser<set<int> >t_serialiser;
  t_serialiser . serialise ( t );

  map<int,set<int> >u;
  u . insert ( make_pair ( 5,t ) );
  u . insert ( make_pair ( 7,t ) );
  Container_serialiser<map<int,set<int> > >u_serialiser;
  u_serialiser . serialise ( u );
}
#include <iostream>
#include <map>
#include <set>
#include <utility>

using std :: cout;

using std :: map;

using std :: set;

using std :: make_pair;
using std :: pair;

template<typename T>class serialisation{
public:
  virtual ~serialisation ( );
protected:
  virtual void serialise ( const T t ) = 0;
};

template<typename T>serialisation<T> :: ~serialisation ( ){
}

template<typename T>class serialiser0;

template<>class serialiser0<int>:public serialisation<int>{
public:
  void serialise ( const int t );
};

void serialiser0<int>:: serialise ( const int t ){
  cout << t << '\n';
}

template<typename T>class Container_serialiser0:public serialisation<T>{
public:
  void serialise ( const T t );
private:
  serialiser0<typename T :: value_type>value_serialiser;
};

template<typename T>void Container_serialiser0<T>:: serialise ( const T t ){
  for(typename T :: const_iterator t_iterator = t . begin ( );t_iterator != t . end ( );++ t_iterator){
    value_serialiser . serialise ( * t_iterator );
  }
}

template<typename T>class serialiser1;

template<>class serialiser1<pair<const int,set<int> > >:public serialisation<pair<int,set<int> > >{
public:
  void serialise ( const pair<int,set<int> >t );
private:
  serialiser0<int>t_first_serialiser;

  Container_serialiser0<set<int> >t_second_serialiser;
};

void serialiser1<pair<const int,set<int> > >:: serialise ( const pair<int,set<int> >t ){
  t_first_serialiser . serialise ( t . first );
  t_second_serialiser . serialise ( t . second );
}

/* This is the same as Container_serialiser0!
 */
template<typename T>class Container_serialiser1:public serialisation<T>{
public:
  void serialise ( const T t );
private:
  serialiser1<typename T :: value_type>value_serialiser;
};

template<typename T>void Container_serialiser1<T>:: serialise ( const T t ){
  for(typename T :: const_iterator t_iterator = t . begin ( );t_iterator != t . end ( );++ t_iterator){
    value_serialiser . serialise ( * t_iterator );
  }
}

int main ( ){
  set<int>t;
  t . insert ( 2 );
  t . insert ( 3 );
  Container_serialiser0<set<int> >t_serialiser;
  t_serialiser . serialise ( t );

  map<int,set<int> >u;
  u . insert ( make_pair ( 5,t ) );
  u . insert ( make_pair ( 7,t ) );
  Container_serialiser1<map<int,set<int> > >u_serialiser;
  u_serialiser . serialise ( u );
}
#include <map>
#include <set>
#include <utility>

// For the sake of having a MWE, I'll just write int-s to stdout.
#include <iostream>

template <typename SerialisedType> class Serialiser;

template <typename SerialisedType>
inline void serialise(const SerialisedType &x) {
  Serialiser<SerialisedType>::serialise(x);
}

template <> class Serialiser<int> {
public:
  inline static void serialise(const int &x);
};

template <typename Key> class Serialiser<std::set<Key>> {
public:
  inline static void serialise(const std::set<Key> &x);
};

template <typename T1, typename T2> class Serialiser<std::pair<T1, T2>> {
public:
  inline static void serialise(const std::pair<T1, T2> &x);
};

template <typename Key, typename T>
class Serialiser<std::map<Key, T>> {
public:
  inline static void serialise(const std::map<Key, T> &x);
};

void Serialiser<int>::serialise(const int &x) {
  std::cout << x << "\n";
}

template <typename Key>
void Serialiser<std::set<Key>>::serialise(const std::set<Key> &x) {
  {
    const typename std::set<Key>::const_iterator x_cend = x.cend();

    for (typename std::set<Key>::const_iterator x_iterator = x.cbegin();
         x_iterator != x_cend; ++x_iterator)
      ::serialise(*x_iterator);
  }
}

template <typename T1, typename T2>
void Serialiser<std::pair<T1, T2>>::serialise(const std::pair<T1, T2> &x) {
  ::serialise(x.first);
  ::serialise(x.second);
}

template <typename Key, typename T>
void Serialiser<std::map<Key, T>>::serialise(const std::map<Key, T> &x) {
  {
    const typename std::map<Key, T>::const_iterator x_cend = x.cend();

    for (typename std::map<Key, T>::const_iterator x_iterator = x.cbegin();
         x_iterator != x_cend; ++x_iterator)
      ::serialise(*x_iterator);
  }
}

int main() {
  std::map<int, std::set<int>> u {
    {5, {2, 3}},
    {7, {2, 3}}
  };
  serialise(u);
}
5
2
3
7
2
3