C++ 基于SFINAE的序列化解决方案无法在C++;

C++ 基于SFINAE的序列化解决方案无法在C++;,c++,templates,serialization,sfinae,rapidjson,C++,Templates,Serialization,Sfinae,Rapidjson,我正尝试或多或少地对模板类MState进行一般性序列化。为此,我有一个父抽象类mvvariable,它用以下形式实现了几个序列化函数: template <class Serializer, class SerializedType> void serialize(Serializer& s, const SOME_SPECIFIC_TYPE &t) const; 的实现是基于stl\u sequential\u container的,而的实现是从has\u ser

我正尝试或多或少地对模板类
MState
进行一般性序列化。为此,我有一个父抽象类
mvvariable
,它用以下形式实现了几个序列化函数:

template <class Serializer, class SerializedType>
void serialize(Serializer& s, const SOME_SPECIFIC_TYPE &t) const;
的实现是基于stl\u sequential\u container
的,而
的实现是从has\u serialize
中借来的。这两种方法都经过了检查,似乎都能正常工作:

MState<float> tvar0;
MState<double> tvar1;
MState<std::vector<float> > tvar2;

rapidjson::StringBuffer str_buf;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(str_buf);
writer.StartObject();
tvar0.serialize(writer);  /* --> First function is used. Ok! */
tvar1.serialize(writer);  /* --> First function is used. Ok! */
tvar2.serialize(writer);  /* --> Second function is used, but there's
                           *     substitution failure in the inner call. 
                           **/
writer.EndObject();
该消息继续显示static assert错误,表明以前所有重载的模板函数在替换中都失败了,或者最后一个是最佳选择

为什么当我尝试序列化
tvar0
tvar1
时,
float
的替换在这里“失败”?

问题。。。 代码中至少有两个问题


首先,在
MState::serialize()
中显式指定模板参数:

或者添加一个推断的
SerializedType常量&
参数和一个sfinae约束的伪默认参数或返回类型(**)


第二个问题是,“回退”重载应该位于可能调用它的受约束重载之前:

template <class Serializer, class SerializedType>
void serialize(Serializer&, SerializedType) const:

template <class Serializer, class SerializedType>
void serialize(Serializer& s, const SerializedSeqCntr<SerializedType> &t);

...

非常感谢。你的解决方案刚刚解决了问题。然而,我并不完全理解。我不熟悉SFINAE方法,这是我第一次尝试类似的方法。您是否愿意详细说明“SFINAE检查是非推断上下文”的含义?此外,什么是“sfinae约束的伪默认参数或返回类型”,或者我为什么需要它
In instantiation of ‘void MVariable::serialize(Serializer&, SerializedType) const 
[with Serializer = rapidjson::PrettyWriter<... blah, blah, blah>; 
      SerializedType = float]’:
MVariable::serialize<Serializer, T>(s, m_state);
serialize<Serializer,std::decay_t<decltype(i)>>(s, i);
template <class Serializer, class SerializedType>
void serialize(Serializer&, SerializedType) const:

template <class Serializer, class SerializedType>
void serialize(Serializer& s, const SerializedSeqCntr<SerializedType> &t);

...
template<typename T>
result_type
foo( T arg, std::enable_if_t<std::is_floating_point<T>::value>* = 0 );

template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, result_type>
foo( T arg );