nullptr 作为模板参数
nullptr as a template parameter
我有一个模板:
template <class A, class B>
void func(A* a, B* b){
...
}
在某些情况下,碰巧不需要参数 B* b
,因此,我尝试使用 nullptr:
MyA a;
func(&a, nullptr);
编译器不喜欢那样,因为 nullptr
不知何故不是类型。
我该如何处理这种情况?唯一的想法是在这种情况下只使用虚拟类型。
问题是nullptr
其实不是指针,而是nullptr_t
类型的对象。所以它不能匹配 A*
或 B*
。一种选择是提供一个重载来专门处理 nullptr_t
.
template<class A>
void func(A* a, nullptr_t)
{
func(a, (int*)nullptr);
}
如果您还想允许第一个参数为 nullptr
,您可以再提供 2 个重载。一个只处理第一个参数,一个处理两个参数。
template<class B>
void func(nullptr_t, B* b)
{
func((int*)nullptr, b);
}
void func(nullptr_t, nullptr_t)
{
func((int*)nullptr, (int*)nullptr);
}
对于任何更多的参数,如果没有代码生成,这种方法就变得不可行,因为所需的重载数量是参数数量的指数函数。在那种情况下,我会推荐 jrok 的方法。
除了 建议的重载之外,如果类型 A
和 B
是指针或 std::nullptr_t
,另一个选项是有条件地启用函数:
#include <type_traits>
template<typename T>
struct is_pointer : std::integral_constant<bool,
std::is_pointer<T>::value ||
std::is_same<T, std::nullptr_t>::value
>
{};
template <class A, class B>
typename std::enable_if<
is_pointer<A>::value && is_pointer<B>::value
>::type
func(A a, B b) { }
但有时最简单的就是最好的,所以也许第二次重载 template<class A> func(A*);
就可以完成这项工作。
当您想调用该函数时,您可以执行以下操作而不是其他方式:
func<a, b>(var_a, nullptr);
通过这样做,您只需将模板传递给函数,您就可以拥有自己的类型
这只是另一种 hacky 方法,但它有效:
T* tNullptr = nullptr;
functionWithTemplate(otherArgument1, tNullptr)
我有一个模板:
template <class A, class B>
void func(A* a, B* b){
...
}
在某些情况下,碰巧不需要参数 B* b
,因此,我尝试使用 nullptr:
MyA a;
func(&a, nullptr);
编译器不喜欢那样,因为 nullptr
不知何故不是类型。
我该如何处理这种情况?唯一的想法是在这种情况下只使用虚拟类型。
问题是nullptr
其实不是指针,而是nullptr_t
类型的对象。所以它不能匹配 A*
或 B*
。一种选择是提供一个重载来专门处理 nullptr_t
.
template<class A>
void func(A* a, nullptr_t)
{
func(a, (int*)nullptr);
}
如果您还想允许第一个参数为 nullptr
,您可以再提供 2 个重载。一个只处理第一个参数,一个处理两个参数。
template<class B>
void func(nullptr_t, B* b)
{
func((int*)nullptr, b);
}
void func(nullptr_t, nullptr_t)
{
func((int*)nullptr, (int*)nullptr);
}
对于任何更多的参数,如果没有代码生成,这种方法就变得不可行,因为所需的重载数量是参数数量的指数函数。在那种情况下,我会推荐 jrok 的方法。
除了 A
和 B
是指针或 std::nullptr_t
,另一个选项是有条件地启用函数:
#include <type_traits>
template<typename T>
struct is_pointer : std::integral_constant<bool,
std::is_pointer<T>::value ||
std::is_same<T, std::nullptr_t>::value
>
{};
template <class A, class B>
typename std::enable_if<
is_pointer<A>::value && is_pointer<B>::value
>::type
func(A a, B b) { }
但有时最简单的就是最好的,所以也许第二次重载 template<class A> func(A*);
就可以完成这项工作。
当您想调用该函数时,您可以执行以下操作而不是其他方式:
func<a, b>(var_a, nullptr);
通过这样做,您只需将模板传递给函数,您就可以拥有自己的类型
这只是另一种 hacky 方法,但它有效:
T* tNullptr = nullptr;
functionWithTemplate(otherArgument1, tNullptr)