在模板初始化期间,模板参数列表中的 false 评估为什么?
what does false in template argument list evaluates into during template initialisation?
我刚开始研究 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
class 的部分特化,用作死胡同。当你有
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 函数。
我刚开始研究 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
class 的部分特化,用作死胡同。当你有
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 函数。