C++ 模板专门化与默认值

C++ 模板专门化与默认值,c++,templates,c++11,sfinae,C++,Templates,C++11,Sfinae,我见过这样编写的模板: template<typename T, bool = is_integral<T>::value, bool = is_floating_point<T>::value> struct helper {}; template<typename T> struct helper<T, true, false> { typedef TypeAppropria

我见过这样编写的模板:

    template<typename T, bool = is_integral<T>::value, bool = is_floating_point<T>::value>
    struct helper {};

    template<typename T>
    struct helper<T, true, false>
    {
        typedef TypeAppropriateForThisSpecialization type;
    };
都是一样的

并且helper是专门化的,所以当T是整数而不是浮点时,helper使用它

这是什么意思?这是否意味着有一个专门的 模板类型参数的真-假组合,如果 ommited,通过is_积分和is_浮点计算

代码背后的思想是要么选择定义类型的专用化,要么选择未定义类型的专用化

如果辅助对象的用户未指定默认模板参数。如果类型T是整数而不是浮点值,则应选择专门化,否则应选择非专门化模板

这是一样的吗?这是一个变量声明/定义:

typename helper<T, true, false>::type t;

typename helper<T, is_integral<T>::value, is_floating_point<T>::value>::type t;
typename helper<T, true, false>::type t;
typename helper<T, is_integral<T>::value, is_floating_point<T>::value>::type t;
如果T确实是整数而不是浮点,则上述类型定义将具有相同的结果,否则它们将具有不同的结果,在这种情况下::type可能无效

这种类型的代码可能在SFINAE中使用。请参见示例。您还可以查看boost::enable_if。如果你能给我们举个用法的例子就好了

这个习惯用法将用于基于属性T在重载集中选择不同的函数,而不是类型。有关enable_if的类似用法,请参见下面的示例

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


template <class T>
typename std::enable_if<std::is_floating_point<T>::value>::type foo( T )
{
  std::cout << "T is a float" << std::endl;
}

template <class T>
typename std::enable_if<
  std::is_integral<T>::value &&
  std::is_unsigned<T>::value>::type foo( T )
{
  std::cout << "T is integral and unsigned" << std::endl;
}

template <class T>
typename std::enable_if<
 std::is_integral<T>::value &&
 std::is_signed<T>::value>::type foo( T )
{
  std::cout << "T is integral and signed" << std::endl;
}

template <class T>
typename std::enable_if<
 !(std::is_integral<T>::value || std::is_floating_point<T>::value)>::type
 foo( T )
{
  std::cout << "T is neiter integral nor float" << std::endl;
}

int main()
{
  foo( 10u );
  foo( 10 );
  foo( 10.2 );
  foo( std::string() );
  return 0;
}

你的答案真的很好,我想看到的一件事是实例化的过程,例如helper::type-编译器到底做什么?因为我的理解是,它用来自is_integral和is_floating_point的值填充两个缺少的类型,然后检查这些类型是否存在专门化。。对吗?如果没有指定的模板参数值替代的模板参数,编译器将从默认模板参数派生实际的模板参数。因此,默认模板参数为_integral等,仅当模板的客户机/实例化器未指定自己的参数时才有效,在这种情况下,可根据T的类型选择不同的专门化。这种类型的代码通常用于从重载集中选择不同的函数,基于T类型的公共属性,而不仅仅是T类型。。。因此,例如:为所有类型的T选择这个函数重载,T是整数而不是浮点数;让我困惑的是,编译器a基于通用模板b生成默认类型,然后为刚刚生成的默认类型找到一个专用模板。因此,编译器在模板实例化时会考虑是否存在显式参数。如果不是,则它考虑范围内C++模板11 14.1标准10中所有模板声明的所有默认参数。选择实际模板参数后,实现/选择适用的专门化,是。
typename helper<T, true, false>::type t;
typename helper<T, is_integral<T>::value, is_floating_point<T>::value>::type t;
#include <type_traits>
#include <iostream>
#include <string>


template <class T>
typename std::enable_if<std::is_floating_point<T>::value>::type foo( T )
{
  std::cout << "T is a float" << std::endl;
}

template <class T>
typename std::enable_if<
  std::is_integral<T>::value &&
  std::is_unsigned<T>::value>::type foo( T )
{
  std::cout << "T is integral and unsigned" << std::endl;
}

template <class T>
typename std::enable_if<
 std::is_integral<T>::value &&
 std::is_signed<T>::value>::type foo( T )
{
  std::cout << "T is integral and signed" << std::endl;
}

template <class T>
typename std::enable_if<
 !(std::is_integral<T>::value || std::is_floating_point<T>::value)>::type
 foo( T )
{
  std::cout << "T is neiter integral nor float" << std::endl;
}

int main()
{
  foo( 10u );
  foo( 10 );
  foo( 10.2 );
  foo( std::string() );
  return 0;
}