C++ 如何使用std::is_integral选择实现?

C++ 如何使用std::is_integral选择实现?,c++,templates,c++11,typetraits,C++,Templates,C++11,Typetraits,如果std::is\u integral::value为true,我将尝试返回一个int64\t 否则,我想调用对象上的_int64t 我下面的尝试失败了,因为不允许对函数模板进行部分专业化 代码 如果满足以下条件,您可以使用std::enable\u: 函数模板不能部分专门化,一般来说,使用函数模板专门化不是一个好主意 实现所需功能的一种方法是使用一种称为标记分派的技术,它基本上包括提供一个转发器函数,该函数根据额外伪参数的值选择正确的重载: #include <type_traits&

如果std::is\u integral::value为true,我将尝试返回一个int64\t

否则,我想调用对象上的_int64t

我下面的尝试失败了,因为不允许对函数模板进行部分专业化

代码

如果满足以下条件,您可以使用std::enable\u:


函数模板不能部分专门化,一般来说,使用函数模板专门化不是一个好主意

实现所需功能的一种方法是使用一种称为标记分派的技术,它基本上包括提供一个转发器函数,该函数根据额外伪参数的值选择正确的重载:

#include <type_traits>
#include <cstdint>

template<class T>
int64_t to_int64t( const T& t, std::true_type )
{
    return t;
}

template<class T>
int64_t to_int64t( const T& t, std::false_type )
{
    return t.to_int64t();
}

template<class T>
int64_t to_int64t( const T& t )
{
    return to_int64t(t, std::is_integral<T>());
}

int main()
{
    int64_t i = 64;
    auto x = to_int64t( i );
}
还有另一种可能,虽然更详细,但可以定义帮助器类模板,该模板可以在详细名称空间中部分专用,并提供一个全局转发器-我不会在本用例中使用此技术,但我将展示它,因为它可能在相关设计情况下派上用场:

#include <type_traits>
#include <cstdint>

namespace detail
{
    template<class T, bool = std::is_integral<T>::value>
    struct helper { };

    template<class T>
    struct helper<T, true>
    {
        static int64_t to_int64t( const T& t )
        {
            return t;
        }
    };

    template<class T>
    struct helper<T, false>
    {
        static int64_t to_int64t( const T& t )
        {
            return t.to_int64t();
        }
    };
}

template<class T>
int64_t to_int64t( const T& t )
{
    return detail::helper<T>::to_int64t(t);
}

int main()
{
    int64_t i = 64;
    auto x = to_int64t( i );
}

哦,天哪,这真漂亮第二个是否为您编译?我得到错误C4519:默认模板参数只允许在类上使用template@Alon:C++11引入的函数模板上的默认模板参数,因此您应该使用std=C++11选项编译。如果不支持此选项,您可能必须将编译器升级到最新版本。谢谢,我想这只在gcc Im中可用VS@Alon:是的,这称为SFINAE替换失败不是错误:编译器尝试实例化函数模板的签名,如果失败,它只是从重载集中丢弃相应的函数,只考虑其他可行的函数。可能的重复:我认为它的实现比公认的更好?这不管用吗?
#include <type_traits>
#include <cstdint>

template<class T>
int64_t to_int64t( const T& t, std::true_type )
{
    return t;
}

template<class T>
int64_t to_int64t( const T& t, std::false_type )
{
    return t.to_int64t();
}

template<class T>
int64_t to_int64t( const T& t )
{
    return to_int64t(t, std::is_integral<T>());
}

int main()
{
    int64_t i = 64;
    auto x = to_int64t( i );
}
#include <type_traits>
#include <cstdint>

template<class T, typename std::enable_if<
    std::is_integral<T>::value>::type* = nullptr>
int64_t to_int64t( const T& t )
{
    return t;
}

template<class T, typename std::enable_if<
    !std::is_integral<T>::value>::type* = nullptr>
int64_t to_int64t( const T& t )
{
    return t.to_int64t();
}

int main()
{
    int64_t i = 64;
    auto x = to_int64t( i );
}
#include <type_traits>
#include <cstdint>

namespace detail
{
    template<class T, bool = std::is_integral<T>::value>
    struct helper { };

    template<class T>
    struct helper<T, true>
    {
        static int64_t to_int64t( const T& t )
        {
            return t;
        }
    };

    template<class T>
    struct helper<T, false>
    {
        static int64_t to_int64t( const T& t )
        {
            return t.to_int64t();
        }
    };
}

template<class T>
int64_t to_int64t( const T& t )
{
    return detail::helper<T>::to_int64t(t);
}

int main()
{
    int64_t i = 64;
    auto x = to_int64t( i );
}