Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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_Sfinae_Boost Serialization - Fatal编程技术网

C++ 在编译时迭代检查函数是否存在

C++ 在编译时迭代检查函数是否存在,c++,templates,sfinae,boost-serialization,C++,Templates,Sfinae,Boost Serialization,关于我现在面临的一个问题,我有一个问题。 在C++中,我创建了一个帮助器,它能够检测给定模板方法的模板参数是否实现了序列化< /Cord>方法(BooSooServices实现)。 helper可以完美地处理我可以抛出的大多数类,但是我想如下扩展它的功能 假设我有一个Foo类,它具有serialize方法。 我希望我可以将任何嵌套的受支持容器vector传递给它,因为vector、list和array提供了序列化方法 如何在包含的类型中迭代深入到未实现value\u类型成员的类型 先谢谢你 这是

关于我现在面临的一个问题,我有一个问题。 在C++中,我创建了一个帮助器,它能够检测给定模板方法的模板参数是否实现了<代码>序列化< /Cord>方法(BooSooServices实现)。 helper可以完美地处理我可以抛出的大多数类,但是我想如下扩展它的功能

假设我有一个
Foo
类,它具有serialize方法。 我希望我可以将任何嵌套的受支持容器
vector
传递给它,因为
vector
list
array
提供了
序列化方法

如何在包含的类型中迭代深入到未实现
value\u类型
成员的类型

先谢谢你

这是我当前的解决方案:

namespace check
{
///A set of classes and struct to be sure the serialised object is either trivial or implementing custom serialize
template <class Type, class Archive, typename = typename std::enable_if<std::is_class<Type>::value>::type>
class is_boost_serializable
{
 private:
  struct TypeOverloader {
    void serialize(Archive& ar, const unsigned int version) {}
  };
  struct TypeExt : public Type, public TypeOverloader {
  };
  template <typename T, T t>
  class DeductionHelper
  {
  };

  class True
  {
    char m;
  };
  class False
  {
    True m[2];
  };

  template <typename TestType>
  static False deduce(TestType*, DeductionHelper<void (TypeOverloader::*)(), &TestType::serialize>* = 0);
  static True deduce(...);

 public:
  static const bool value = (sizeof(True) == sizeof(deduce((TypeExt*)(0))));
};
} // namespace check
名称空间检查
{
///一组类和结构,以确保序列化对象是平凡的或实现自定义序列化
模板
类是可序列化的
{
私人:
结构类型重载器{
void序列化(存档&ar,常量unsigned int version){}
};
结构类型EXT:公共类型,公共类型重载{
};
模板
类扣减帮助器
{
};
类真
{
charm;
};
类假
{
真m[2];
};
模板
静态假推断(TestType*,DeclarationHelper*=0);
静态真推断(…);
公众:
静态常量布尔值=(sizeof(True)=sizeof(推断((TypeExt*)(0)));
};
}//名称空间检查
#包括
#包括
模板
使用void\u t=void;
模板
结构是可序列化的:std::false_type{};
模板

struct是_boost_serializable根据Piotr令人敬畏的建议,我扩展了他的解决方案,以便与boost可串行化的类型(int、char、double…)兼容

这是我定制的解决方案

干杯,谢谢

#include <type_traits>
#include <utility>
#include <vector>
#include <list>
#include <array>
#include <cassert>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/set.hpp>
#include <boost/type_traits.hpp>

struct Arc
{
};

struct Foo
{
    int pippo = 0;

    friend class boost::serialization::access;

    template <class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar &pippo;
    }
};

struct Bar
{
};

template <typename...>
using void_t = void;

template <typename Type, typename Archive = boost::archive::binary_oarchive, typename = void_t<>>
struct is_boost_serializable_base : std::false_type
{
};

template <class Type, typename Archive>
struct is_boost_serializable_base<Type, Archive,
                                  void_t<decltype(std::declval<Type &>().serialize(std::declval<Archive &>(), 0))>>
    : std::true_type
{
};

template <typename Type, typename Archive>
struct is_boost_serializable_base<Type, Archive,
                                  typename std::enable_if<boost::serialization::is_bitwise_serializable<Type>::value>::type>
    : std::true_type
{
};

template <typename Type, typename Archive = boost::archive::binary_oarchive, typename = void_t<>>
struct is_boost_serializable
    : is_boost_serializable_base<Type, Archive>
{
};

template <typename Type, typename Archive>
struct is_boost_serializable<Type, Archive, void_t<typename Type::value_type>>
    : is_boost_serializable<typename Type::value_type, Archive>
{
};

template <typename Type>
struct is_boost_serializable<Type, boost::archive::binary_oarchive, void_t<typename Type::value_type>>
    : is_boost_serializable<typename Type::value_type, boost::archive::binary_oarchive>
{
};

int main()
{
    static_assert(is_boost_serializable<Foo, Arc>::value, "!");
    static_assert(is_boost_serializable<std::vector<std::list<std::array<Foo, 8>>>, Arc>::value, "!");
    static_assert(is_boost_serializable<std::vector<std::list<std::array<int, 8>>>, Arc>::value, "!");
    static_assert(not is_boost_serializable<std::vector<std::list<std::array<Bar, 8>>>, Arc>::value, "!");
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构弧
{
};
结构Foo
{
int-pippo=0;
好友类boost::serialization::access;
模板
无效序列化(存档和ar,常量未签名整数版本)
{
ar&pippo;
}
};
结构条
{
};
模板
使用void\u t=void;
模板
结构是可序列化的:std::false\u类型
{
};
模板
结构是可序列化的基础
:std::true\u类型
{
};
模板
结构是可序列化的基础
:std::true\u类型
{
};
模板
结构是可序列化的
:是可串行化的吗
{
};
模板
结构是可序列化的
:可序列化吗
{
};
模板
结构是可序列化的
:可序列化吗
{
};
int main()
{
静态断言(是可序列化的::值,“!”;
静态断言(是可序列化的::值,“!”;
静态断言(是可序列化的::值,“!”;
静态断言(不是可序列化的::值,“!”;
}

感谢您的解决方案,它对我很有效。我添加了一些特性,例如对基类型的支持(基本类型是可序列化的)。我将我的扩展解决方案作为附加答案发布。@jetstream欢迎您。您最初的解决方案使用了旧技术的混合,这些技术在C++11中被表达式SFINAE取代。另一方面,特征的递归实例化是一种常见的技术。通过C++2a的检测习惯用法,这段代码可以缩短得更多。我正在尝试移动我在SFINAE中的第一步。我从你的帖子中学到了更多。谢谢
#include <type_traits>
#include <utility>
#include <vector>
#include <list>
#include <array>
#include <cassert>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/set.hpp>
#include <boost/type_traits.hpp>

struct Arc
{
};

struct Foo
{
    int pippo = 0;

    friend class boost::serialization::access;

    template <class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar &pippo;
    }
};

struct Bar
{
};

template <typename...>
using void_t = void;

template <typename Type, typename Archive = boost::archive::binary_oarchive, typename = void_t<>>
struct is_boost_serializable_base : std::false_type
{
};

template <class Type, typename Archive>
struct is_boost_serializable_base<Type, Archive,
                                  void_t<decltype(std::declval<Type &>().serialize(std::declval<Archive &>(), 0))>>
    : std::true_type
{
};

template <typename Type, typename Archive>
struct is_boost_serializable_base<Type, Archive,
                                  typename std::enable_if<boost::serialization::is_bitwise_serializable<Type>::value>::type>
    : std::true_type
{
};

template <typename Type, typename Archive = boost::archive::binary_oarchive, typename = void_t<>>
struct is_boost_serializable
    : is_boost_serializable_base<Type, Archive>
{
};

template <typename Type, typename Archive>
struct is_boost_serializable<Type, Archive, void_t<typename Type::value_type>>
    : is_boost_serializable<typename Type::value_type, Archive>
{
};

template <typename Type>
struct is_boost_serializable<Type, boost::archive::binary_oarchive, void_t<typename Type::value_type>>
    : is_boost_serializable<typename Type::value_type, boost::archive::binary_oarchive>
{
};

int main()
{
    static_assert(is_boost_serializable<Foo, Arc>::value, "!");
    static_assert(is_boost_serializable<std::vector<std::list<std::array<Foo, 8>>>, Arc>::value, "!");
    static_assert(is_boost_serializable<std::vector<std::list<std::array<int, 8>>>, Arc>::value, "!");
    static_assert(not is_boost_serializable<std::vector<std::list<std::array<Bar, 8>>>, Arc>::value, "!");
}