1

I need trait to check if serialization is possible using cereal. I've already used

cereal::traits::is_output_serializable<T, cereal::BinaryOutputArchive>
cereal::traits::detail::count_output_serializers<T, cereal::BinaryOutputArchive>

(plus the symmetric version for input serialization).

Putting such checks in if constexpr passes (evaluates to true even though my type is not serializable) but later on it breaks within cereal saying that the very same trait failed(!) I'm using T=cv::Mat.

  • Is there an alternative check available?
  • Any idea why such a thing may fail? Is my archive type wrong?
Lorah Attkins
  • 5,331
  • 3
  • 29
  • 63
  • 1
    could you, maybe, post some of the code for the `if constexpr` that passes and then fails? – ben10 Jun 24 '21 at 08:45
  • My own test with concepts gave me the same result. Interesting. – Timo Jun 24 '21 at 08:55
  • @Timo Well, both concepts and `std::is_invocable` will check if the expression is well formed. Unfortunately, since these functions are templates in cereal, they are indeed type-wise always invocable. What happens is that during compilation a static assertion is triggered, and that's when things fail. So Maybe checking with those methods stops earlier than the actual compilation – Lorah Attkins Jun 24 '21 at 09:01
  • @LorahAttkins yeah I was just digging through cereal and found the asserts as well. They're not concept friendly it looks like. However the trait from cereal itself works for me with a custom type in a static assert. Can you post how you use the trait? – Timo Jun 24 '21 at 09:04

1 Answers1

1

I wrote my own based on some static asserts I found in Cereal. I have a base case with a bunch of specialisations I need for my own code. The specialisations are needed as the base case is true for std::shared_ptr<T> even if T isn't itself serialisable.

    /// Meta programming constant, can you serialise the type T to the Cereal archive ARCHIVE?
    template<typename ARCHIVE, typename T>
    static constexpr bool kHasCerealOutputArchiver
      = not std::is_pointer<T>::value and cereal::traits::detail::count_output_serializers<T, ARCHIVE>::value != 0;

    // specialisation for vectors
    template<typename ARCHIVE, typename T, typename A>
    static constexpr bool kHasCerealOutputArchiver<ARCHIVE, std::vector<T, A>> = kHasCerealOutputArchiver<ARCHIVE, T>;

    // specialisation for shared_ptrs
    template<typename ARCHIVE, typename T>
    static constexpr bool kHasCerealOutputArchiver<ARCHIVE, std::shared_ptr<T>> = kHasCerealOutputArchiver<ARCHIVE, T>;

    // specialisation for shared_ptrs to const
    template<typename ARCHIVE, typename T>
    static constexpr bool kHasCerealOutputArchiver<ARCHIVE, std::shared_ptr<const T>> = kHasCerealOutputArchiver<ARCHIVE, T>;


    /// Meta programming constant, can you serialise the type T from the Cereal archive ARCHIVE?
    template<typename ARCHIVE, typename T>
    static constexpr bool kHasCerealInputArchiver
      = not std::is_pointer<T>::value and cereal::traits::detail::count_input_serializers<T, ARCHIVE>::value != 0;

    // specialisation for vectors
    template<typename ARCHIVE, typename T, typename A>
    static constexpr bool kHasCerealInputArchiver<ARCHIVE, std::vector<T, A>> = kHasCerealInputArchiver<ARCHIVE, T>;

    // specialisation for shared_ptrs
    template<typename ARCHIVE, typename T>
    static constexpr bool kHasCerealInputArchiver<ARCHIVE, std::shared_ptr<T>> = kHasCerealInputArchiver<ARCHIVE, T>;

    // specialisation for shared_ptrs to const
    template<typename ARCHIVE, typename T>
    static constexpr bool kHasCerealInputArchiver<ARCHIVE, std::shared_ptr<const T>> = kHasCerealInputArchiver<ARCHIVE, T>;

brunobignose
  • 106
  • 1
  • 6