#include <cassert>
#include <type_traits>
#include <iostream>

class CByteArray { public: CByteArray() {}};

class Variant {};

template<typename T>
CByteArray serializePodType(const T&)
{
  printf("serializePodType\n");
  return CByteArray();
}

CByteArray serializeVariant(const Variant& v)
{
  printf("serializeVariant\n");
  return CByteArray();
}

template <typename T>
typename std::enable_if<std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
  return serializePodType(value);
}

template <typename T>
typename std::enable_if<std::is_convertible<T, Variant>::value && !std::is_pod<T>::value, CByteArray>::type serialize(const T& value)
{
  return serializeVariant(Variant(value));
}

class ConvertibleToVariant : public Variant { virtual void foo(); };

struct POD {};

struct NonPOD { virtual void foo(); };

int main()
{
  POD pod;
  ConvertibleToVariant ctv;
  //NonPOD nonpod;
  
  const auto ctv_serialised = serialize(ctv);
  const auto pod_serialised = serialize(pod);
  //const auto nonpod_serialised = serialize(nonpod);
}