SFINAE简单实例

SFINAE(Substitution failure is not an error),是C++11以来推出的一个重要概念,这里,只是简单举一个例子,可能会有人需要。

// 添加 scalar numeric conversion function,实现源自 C++ programming language(4th)
// 用来防止使用static转换的时候,值发生改变

// there is no implicit conversion from Source to Target
template <typename Target, typename Source,
    typename = std::enable_if_t<!std::is_reference_v<Target> &&
    !std::is_same_v<std::common_type_t<std::decay_t<Target>, std::decay_t<Source>>, std::decay_t<Target>>, int>>
    inline Target narrow_cast(Source v)
{
    static_assert(std::is_arithmetic<Source>::value, "The parameter of narrow_cast should be arithmetic");
    static_assert(std::is_arithmetic<Target>::value, "The return value of narrow_cast should be arithmetic");

    // using Target_U = std::remove_reference_t<Target>;
    // using Source_U = std::remove_reference_t<Source>;

    auto r = static_cast<Target>(v);
    if (static_cast<Source>(r) != v)
        throw std::runtime_error("narrow_cast<>() failed");
    return r;
}

// there is implicit conversion from Source to Target
template <typename Target, typename Source,
    typename = std::enable_if_t<!std::is_reference_v<Target> &&
    std::is_same_v<std::common_type_t<std::decay_t<Target>, std::decay_t<Source>>, std::decay_t<Target>>, int>>
    inline constexpr std::remove_reference_t<Source> narrow_cast(Source v)
{
    static_assert(std::is_arithmetic<Source>::value, "The parameter of narrow_cast should be arithmetic");
    static_assert(std::is_arithmetic<Target>::value, "The return value of narrow_cast should be arithmetic");

    return std::remove_reference_t<Source>(v);
}
原文地址:https://www.cnblogs.com/albizzia/p/8607317.html