std::enable_if 如何工作?
我刚刚问了这个问题:std::numeric_limits 作为条件>
我了解 std::enable_if 将有条件地定义方法的返回类型导致方法编译失败的用法.
template类型名称 std::enable_if<std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isInt(bar);} 我不明白的是第二个参数和对 std::enable_if 的看似毫无意义的赋值,当它被声明为模板语句的一部分时,如 Rapptz answer.
template::value, int>::type = 0>void foo(const T& bar) { isInt();} 解决方案 正如 40two 在评论中提到的,理解替换失败不是错误是理解的先决条件std::enable_if.
std::enable_if 是一个专门的模板,定义为:
template结构 enable_if {};模板struct enable_if{ typedef T 类型;}; 这里的关键在于typedef T type仅在bool Cond为true时才定义.
现在有了对 std::enable_if 的理解,很明显 void foo(const T &bar) { isInt(bar);} 定义为:
template类型名称 std::enable_if<std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isInt(bar);} 如firda 的答案所述,= 0 是第二个模板的默认值范围.template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> 中默认的原因是两个选项都可以用 foo<调用int >( 1 );.如果 std::enable_if 模板参数没有被默认,调用 foo 将需要两个模板参数,而不仅仅是 int.
一般注意,通过明确输入 typename std::enable_if 但 void 是 std::enable_if 的默认第二个参数,如果你有 c++14 enable_if_t 是一个定义的类型,应该使用.所以返回类型应该压缩为:std::enable_if_t
给 visual- 的用户的特别说明-工作室 visual-studio-2013:不支持默认模板参数,因此您只能在函数返回时使用 enable_if:std::numeric_limits 作为条件
I just asked this question: std::numeric_limits as a Condition
I understand the usage where std::enable_if will define the return type of a method conditionally causing the method to fail to compile.
template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isInt(bar); }
What I don't understand is the second argument and the seemingly meaningless assignment to std::enable_if when it's declared as part of the template statement, as in Rapptz answer.
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& bar) { isInt(); }
解决方案
As is mentioned in comment by 40two, understanding of Substitution Failure Is Not An Error is a prerequisite for understanding std::enable_if.
std::enable_if is a specialized template defined as:
template<bool Cond, class T = void> struct enable_if {};
template<class T> struct enable_if<true, T> { typedef T type; };
The key here is in the fact that typedef T type is only defined when bool Cond is true.
Now armed with that understanding of std::enable_if it's clear that void foo(const T &bar) { isInt(bar); } is defined by:
template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isInt(bar); }
As mentioned in firda's answer, the = 0 is a defaulting of the second template parameter. The reason for the defaulting in template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> is so that both options can be called with foo< int >( 1 );. If the std::enable_if template parameter was not defaulted, calling foo would require two template parameters, not just the int.
General note, this answer is made clearer by explicitly typing out typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type but void is the default second parameter to std::enable_if, and if you have c++14 enable_if_t is a defined type and should be used. So the return type should condense to: std::enable_if_t<std::numeric_limits<T>::is_integer>
A special note for users of visual-studio prior to visual-studio-2013: Default template parameters aren't supported, so you'll only be able to use the enable_if on the function return: std::numeric_limits as a Condition
相关文章