为什么函数模板不理解 NULL 但可以使用 nullptr?
Why function template does not understand NULL but works with nullptr?
我有一个功能
int f(std::shared_ptr<MyClass> sptr);
之后,我编写了以下模板,以便能够调用它(和其他一些)函数:
template <typename Func, typename ArgType>
auto call(Func func, ArgType arg) -> decltype(func(arg))
{
return func(arg);
}
当我尝试将此模板与 NULL 一起使用时,为什么在第三行出现错误?
auto r0 = f(0); // OK
auto r1 = call(f, nullptr); // OK
auto r2 = call(f, NULL); // ERROR! WHY??
1>------ Build started: Project: ConsoleApplication1, Configuration: Debug x64 ------
1> main.cpp
1>main.cpp(245): error C2893: Failed to specialize function template 'unknown-type call(Func,Arg)'
1> With the following template arguments:
1> 'Func=int (__cdecl *)(std::shared_ptr<MyClass>)'
1> 'Arg=int'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
线索在这里:
Arg=int
NULL
必须是一个空指针常量,在 C++11 之前,这意味着它必须是一个值为零的整数常量。在您的实现中,它的类型为 int
,并且可能是文字 0
.
因此模板参数被推导为int
,无法转换为shared_ptr
,因此出现错误。
至于其他:
auto r0 = f(0); // OK
文字 0
可以被视为空指针常量,如果直接传递给函数,则转换为 shared_ptr
。在call
中,参数不是文字,而是int
类型的变量,无法转换。
auto r1 = call(f, nullptr); // OK
nullptr
有自己的类型,可以转换为 shared_ptr
.
因为在 C++ 中 NULL
通常被定义为 0
,这是一个 int
。因此模板类型 ArgType
被推断为 int
并且您无法将 int
转换为 std::shared_ptr
.
请注意,它适用于例如f(0)
(然后应该为 f(NULL)
工作)但那是因为编译器知道 0
在这种情况下是一个空指针。在 call
函数中,编译器不知道变量 arg
会有什么值,只知道它的类型 int
不能隐式转换为指针。
我有一个功能
int f(std::shared_ptr<MyClass> sptr);
之后,我编写了以下模板,以便能够调用它(和其他一些)函数:
template <typename Func, typename ArgType>
auto call(Func func, ArgType arg) -> decltype(func(arg))
{
return func(arg);
}
当我尝试将此模板与 NULL 一起使用时,为什么在第三行出现错误?
auto r0 = f(0); // OK
auto r1 = call(f, nullptr); // OK
auto r2 = call(f, NULL); // ERROR! WHY??
1>------ Build started: Project: ConsoleApplication1, Configuration: Debug x64 ------
1> main.cpp
1>main.cpp(245): error C2893: Failed to specialize function template 'unknown-type call(Func,Arg)'
1> With the following template arguments:
1> 'Func=int (__cdecl *)(std::shared_ptr<MyClass>)'
1> 'Arg=int'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
线索在这里:
Arg=int
NULL
必须是一个空指针常量,在 C++11 之前,这意味着它必须是一个值为零的整数常量。在您的实现中,它的类型为 int
,并且可能是文字 0
.
因此模板参数被推导为int
,无法转换为shared_ptr
,因此出现错误。
至于其他:
auto r0 = f(0); // OK
文字 0
可以被视为空指针常量,如果直接传递给函数,则转换为 shared_ptr
。在call
中,参数不是文字,而是int
类型的变量,无法转换。
auto r1 = call(f, nullptr); // OK
nullptr
有自己的类型,可以转换为 shared_ptr
.
因为在 C++ 中 NULL
通常被定义为 0
,这是一个 int
。因此模板类型 ArgType
被推断为 int
并且您无法将 int
转换为 std::shared_ptr
.
请注意,它适用于例如f(0)
(然后应该为 f(NULL)
工作)但那是因为编译器知道 0
在这种情况下是一个空指针。在 call
函数中,编译器不知道变量 arg
会有什么值,只知道它的类型 int
不能隐式转换为指针。