c++ - 在模板初始化期间,模板参数列表中的 false 评估为什么?

标签 c++ templates sfinae

<分区>

我刚刚开始研究 SFINAE 以了解它是什么。我正在关注 this tutorial主要是它的意义。但我对代码的关键部分在哪里感到困惑。

在第二个 enable_if 模板参数列表中。有一个 false 和一个模板类型 T 参数。

template <class T>
struct enable_if<false, T>
{};

为什么这里使用了false?在代码中遇到模板实例化时,false 的计算结果是什么?如果有这样的模板参数类型的术语,如果你能分享这个术语,我会很高兴。

这是完整的代码-

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

template <typename T>
class is_container
{
  typedef char true_type;
  struct false_type { true_type _[2]; }; //false_type must be larger then the true_type. 
  template <typename U>
  static true_type has_iterator_checker(typename U::iterator *); //overload 1,.called if the type passed contains an iterator.  and returns a true type.
  template <typename U>
  static false_type has_iterator_checker(...); //if false type is passed //overload 2, called if the type passed DOESN'T contain an iterator. and returns a false type.
public:
  enum
  {
    value = (sizeof(has_iterator_checker<T>(0)) == sizeof(true_type)) //compares the size of the overlad with the true type. if they dont match, value becames false.
  };
};

template <bool Cond, class T = void> //first param is is a bool condition, second param is the return type. 
struct enable_if
{
  typedef T type; //if bool Cond is true, it returns the type.
};

//if bool cond is false, appereantly the following template does nothing and compiler silently fails without throwing error.  
//it seems this is what makes SFINAE a powerfull tool.
//but what i dont understand is that. <false, T>. there is no bool type before false. so what does this false evaluate into whenever compiler
//encounters  it the code?
template <class T>
struct enable_if<false, T>
{};

template <typename T>
typename enable_if<!is_container<T>::value>::type
super_print(T const &t)
{
  std::cout << t << std::endl;
}

template <typename T>
typename enable_if<is_container<T>::value>::type
super_print(T const &t)
{
  typedef typename T::value_type value_type;
  std::copy(t.begin(),
    t.end(),
    std::ostream_iterator<value_type>(std::cout, ", "));
  std::cout << std::endl;
}

int main()
{
  super_print(10); // a condition that is false.
  std::vector<int> b;
  b.push_back(1);
  b.push_back(2);
  b.push_back(3);
  super_print(b);

  return 0;
}

最佳答案

template <class T>
struct enable_if<false, T>
{};

enable_if 的偏特化类,它被用作死胡同。当你有

template <typename T>
typename enable_if<!is_container<T>::value>::type
super_print(T const &t)
{
  std::cout << t << std::endl;
}

编译器评估!is_container<T>::value .如果是true然后

template <bool Cond, class T = void> //first param is is a bool condition, second param is the return type. 
struct enable_if
{
  typedef T type; //if bool Cond is true, it returns the type.
};

enable_if使用和type变成 void因为你没有指定任何内容

typename enable_if<!is_container<T>::value>::type

现在,如果它的计算结果为 false然后

template <class T>
struct enable_if<false, T>
{};

enable_if选择它是因为我们说过这是在 bool 时使用的那个模板的一部分是 false而且它没有 type成员。也就是说

typename enable_if<!is_container<T>::value>::type

是替换失败,因为没有 type成员。由于替换失败不是错误,编译器只是从重载集中删除 then 函数。

关于c++ - 在模板初始化期间,模板参数列表中的 false 评估为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52899118/

相关文章:

c++ - 模板类中的 min_element()

c++ - 如何禁用某些模板类型的类成员函数

c++ - 根据特定成员是否存在来专门化模板

c++ - 如何分隔字符串并将每个部分存储在不同的 vector 中

c++ - 结合组合RNG?带分布的 std::xor_combine 模板?

javascript - Backbone : Using views inside _. 模板

templates - 如何使用 std::enable_if_t 和 std::is_base_of 来检查 SFINAE 的编译时继承?

c++ - 如何在 C++ 中对三元组进行排序?

c++ - 类型特征以检查类型是否可从流和 MSVC 中读取

c++ - 无法累积编译时间常量