enable_if编译问题void=nullptr



有人知道为什么分配type* = 0不起作用,而分配type* = nullptr起作用吗?在这两种情况下,CCD_。感谢

#include <type_traits>
#include <iostream>
template <class T,
typename std::enable_if<std::is_integral<T>::value>::type* = 0>
void do_stuff(T& t) {
std::cout << "do_stuff integraln";
}
#if 0 // works
template <class T,
typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
void do_stuff(T& t) {
std::cout << "do_stuff integraln";
}
#endif

struct S {};
int main(int argc, char *argv[])
{
int i = 1;
do_stuff(i);
return 0;
}

编译:

clang++ -pedantic -Wall -std=c++11 test190.cc && ./a.out
test190.cc:23:5: error: no matching function for call to 'do_stuff'
do_stuff(i);
^~~~~~~~
test190.cc:6:6: note: candidate template ignored: substitution failure
[with T = int]: null non-type template argument must be cast to template
parameter type 'typename
std::enable_if<std::is_integral<int>::value>::type *' (aka 'void *')
void do_stuff(T& t) {
^
1 error generated.

从技术上讲,这是因为非类型模板参数必须是一个"转换常数表达式";参数类型的。这意味着参数本身必须是一个常量表达式,并且它到所需参数类型的转换必须仅使用[expr.const]/4中指定的转换。

根据[expr.const]/4,只允许从std::nullptr_t进行空指针转换。换句话说,在转换的常量表达式中,不允许将从0到空指针值的转换作为隐式转换序列的一部分。

然而,将static_cast<T*>(0)指定为T*类型的非类型模板参数的模板参数是完全合法的。换句话说,允许从0转换为null指针作为常量表达式的一部分。只有当转换在某个点完成时——在计算参数之后,并且在将自变量类型转换为型时——标准才禁止转换

我不知道这条规则的理由。

**nullptr和0不相同。**

如需非常清楚的解释,请参阅以下内容:

https://hackernoon.com/what-exactly-is-nullptr-in-c-94d63y6t

@brian提供了一个非常好的技术答案,但我觉得有必要添加这个答案,因为我们不应该再尝试使用0作为指针值。

相关内容

最新更新