首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用std::is_integral<>来选择实现?

如何使用std::is_integral<>来选择实现?
EN

Stack Overflow用户
提问于 2013-03-24 13:19:03
回答 2查看 10.8K关注 0票数 15

如果int64_t是真的话,我正在尝试返回std::is_integral<>::value

否则,我会调用对象上的to_int64t()

我在下面的尝试失败了,因为不允许部分专门化函数模板。

代码语言:javascript
复制
#include <type_traits>
#include <cstdint>

template<class T,bool is_integral_type>
int64_t to_int64t( const T& t )
{
        return t;
}

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

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

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

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-24 13:23:28

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

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

代码语言:javascript
复制
#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 );
}

另一种可能是使用基于std::enable_if的经典的SFINAE技术。这就是它的样子(注意,由于C++11允许函数模板上的默认模板参数):

代码语言:javascript
复制
#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 );
}

还有一种可能,尽管更详细,是在detail命名空间中定义助手类模板(可以是部分专门化的),并提供全局转发器--我不会在这个用例中使用这种技术,但我展示它是因为它在相关的设计场景中可能有用:

代码语言:javascript
复制
#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 );
}
票数 32
EN

Stack Overflow用户

发布于 2013-03-24 13:23:22

您可以只使用std::enable_if

代码语言:javascript
复制
template<class T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
int64_t to_int64t( const T& t )
{
        return t;
}

template<class T, typename std::enable_if<!std::is_integral<T>::value, int>::type = 0>
int64_t to_int64t( const T& t )
{
        return t.to_int64t();
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15598939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档