此模板 header 中发生了什么?

What is happenning in this template header?

关于如何使用谷物序列化特征矩阵,有一个非常有用的答案: Serializing Eigen::Matrix using Cereal library

我复制并验证了此代码有效,但我很难理解 header:

中发生的事情
template <class Archive, class _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> inline
typename std::enable_if<traits::is_output_serializable<BinaryData<_Scalar>, Archive>::value, void>::type
save(Archive & ar, Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> const & m)
{
    int32_t rows = m.rows();
    int32_t cols = m.cols();
    ar(rows);
    ar(cols);
    ar(binary_data(m.data(), rows * cols * sizeof(_Scalar)));
}

第一行采用谷物档案类型,然后是所有需要的特征模板参数。

我不是100%确定第二行是干什么的,好像是在声明运行类型?但我无法理解该类型的含义。

另外(如果可能,但不是回答所必需的)

为什么这不起作用? (我没有检查,它不会编译):



template <class Archive>
void serialize( Archive& archive, Eigen::Vector2f& vec )
{
    archive(
        CEREAL_NVP((float&)vec[0]),
        CEREAL_NVP((float&)vec[1])
    );
}

template <class Archive>
void serialize( Archive& archive, Eigen::Vector3f& vec )
{
    archive(
        CEREAL_NVP((float&)vec[0]),
        CEREAL_NVP((float&)vec[1]),
        CEREAL_NVP((float&)vec[2])
    );
}

模板使用 SFINAE(替换失败不是错误)来限制此函数采用的模板参数。

基本上如果编译器认为模板函数的函数签名是错误的,它会简单地忽略这个函数而不是产生编译器错误。

typename std::enable_if<traits::is_output_serializable<BinaryData<_Scalar>, Archive>::value, void>::type
如果 traits::is_output_serializable<BinaryData<_Scalar>, Archive>::value 的计算结果为 true,则

实际上是 void,如果计算结果为 false.

,则会导致错误的签名