nullptr作为模板参数

时间:2015-06-07 18:39:24

标签: c++ templates nullptr

我有一个模板:

int foo2(int k) //function defining
{
 int x=0;     // O(1)
 while(n>0)    // O(log(n))
 {
  int i;      // another O(log(n)) because its inside the loop 

  for(i=0;i<n;i++)     // O((n+1)*log(n)) this loop happens inside the while loop
  {
   x += i;      //  O(n*log(n)) happens inside the while and for loops
  }

  n /=2;       // O(log(n) because its inside the while loop and outside the for loop
  }
}

在某些情况下,不需要参数template <class A, class B> void func(A* a, B* b){ ... } ,因此我尝试使用nullptr:

B* b

编译器不喜欢这样,因为MyA a; func(&a, nullptr); 不是某种类型。

我该如何处理这种情况?唯一的想法是在这种情况下使用虚拟类型。

4 个答案:

答案 0 :(得分:9)

问题是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的方法。

答案 1 :(得分:2)

除了Benjamin Lindley建议的重载外,如果类型AB是指针或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*);可以完成这项工作。

答案 2 :(得分:0)

当您想要调用该功能时,您可以执行以下操作而不是其他方式:

    func<a, b>(var_a, nullptr);

通过这样做,您只需将模板传递给函数,您就可以拥有自己的类型

答案 3 :(得分:0)

这是迄今为止我发现的最好的一线解决方案:

const T* const tNullptr = nullptr;
functionWithTemplate(tNullptr, otherArgument1)