C++ 利用函数模板和SFINAE进行参数识别

C++ 利用函数模板和SFINAE进行参数识别,c++,c++11,template-meta-programming,sfinae,typetraits,C++,C++11,Template Meta Programming,Sfinae,Typetraits,将函数模板分为三组:一组生成接受积分的函数,一组接受浮点运算,另一组接受任何其他运算(这比你想象的要简单) #include <string> #include <iostream> #include <type_traits> template<typename T> std::string to_string( const T& val, typename std::enable_if< std::is_int

将函数模板分为三组:一组生成接受积分的函数,一组接受浮点运算,另一组接受任何其他运算(这比你想象的要简单)

#include <string>
#include <iostream>
#include <type_traits>

template<typename T>
std::string to_string(
    const T& val, 
    typename std::enable_if< std::is_integral<T>::value
                           >::type * = nullptr)
 { return "case integral"; }

template<typename T>
std::string to_string(
    const T& val, 
    typename std::enable_if< std::is_floating_point<T>::value 
                           >::type * = nullptr)
 { return "case floating"; }

template<typename T>
std::string to_string(
    const T& val, 
    typename std::enable_if<    (false == std::is_integral<T>::value)
                             && (false == std::is_floating_point<T>::value)
                           >::type * = nullptr)
 { return "case generic"; }

int main ()
 {
   std::cout << to_string(0) << std::endl;        // print case integral
   std::cout << to_string(0.0) << std::endl;      // print case float
   std::cout << to_string("0.000") << std::endl;  // print case generic
 }
#包括
#包括
#包括
模板
std::字符串到_字符串(
康斯特T&val,
如果::type*=nullptr)
{返回“大小写积分”;}
模板
std::字符串到_字符串(
康斯特T&val,
typename std::enable_if::type*=nullptr)
{返回“大小写浮动”;}
模板
std::字符串到_字符串(
康斯特T&val,
typename std::enable_if<(false==std::is_integral::value)
&&(false==std::is_浮点::值)
>::type*=nullptr)
{返回“case-generic”;}
int main()
{

非常感谢您,std::可以很好地工作。有趣的是,我几乎没有遇到过具有类型特征的布尔逻辑的例子,包括比亚恩的参考书。为什么不使用
std::enable_if::value&&!std::is_floating_point::value
而不是
(false==…)
?@em2er-嗯……我想这是个人品味的问题,但读了它,我发现
false==variable
!variable
template<typename T>
std::string to_string(
    const T& val, 
    typename std::enable_if<
            std::is_same<bool, T>::value
    >::type* = 0)
{
    return val ? "true" : "false";
}

template<typename T>
std::string to_string(
    const T& val, 
    typename std::enable_if<
            std::is_integral<T>::value
        &&  (false == std::is_same<bool, T>::value)
    >::type* = 0)
{
    return "integral, but not bool";
}
#include <string>
#include <iostream>
#include <type_traits>

template<typename T>
std::string to_string(
    const T& val, 
    typename std::enable_if< std::is_integral<T>::value
                           >::type * = nullptr)
 { return "case integral"; }

template<typename T>
std::string to_string(
    const T& val, 
    typename std::enable_if< std::is_floating_point<T>::value 
                           >::type * = nullptr)
 { return "case floating"; }

template<typename T>
std::string to_string(
    const T& val, 
    typename std::enable_if<    (false == std::is_integral<T>::value)
                             && (false == std::is_floating_point<T>::value)
                           >::type * = nullptr)
 { return "case generic"; }

int main ()
 {
   std::cout << to_string(0) << std::endl;        // print case integral
   std::cout << to_string(0.0) << std::endl;      // print case float
   std::cout << to_string("0.000") << std::endl;  // print case generic
 }