欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SFINAE简单实例

程序员文章站 2022-03-15 12:15:59
SFINAE(Substitution failure is not an error),是C++11以来推出的一个重要概念,这里,只是简单举一个例子,可能会有人需要。 ......

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);
}