没有定义的结构模板的目的是什么?

时间:2015-01-29 07:33:57

标签: c++ templates metaprogramming boost-python

以下是Boost.Python的source code

的片段
template <class T> struct null_ok; // how's it working?

template <class T>
inline null_ok<T>* allow_null(T* p)
{
    return (null_ok<T>*)p;
}

没有前向声明的struct null_ok的定义,而null_ok与模板参数T无关。

Python wiki中,给出了一些提示:

  

处理&LT;&GT; y(null_ok(x))允许y变为NULL

     

处理&LT;&GT; y(x),其中x不是null_ok的结果,永远不会导致NULL y。如果x为NULL

,则抛出异常

我无法弄清楚结构模板null_ok的声明(没有定义)如何达到上述目的?

2 个答案:

答案 0 :(得分:4)

重点是编码&#34;这个指针可以为null&#34;以及指针本身类型中的原始类型。

然后,接受指针的函数模板可以重载以识别null_ok<T>*指针,而不是空指针错误(将其转换回T*)。

您不需要null_ok的定义,因为您可以指向不完整的类型,并且可以防止人们意外地编写null_ok<int> a;之类的内容。

答案 1 :(得分:1)

正好使用您的代码段下面的handle.hpp中的代码(我的评论):

// this is a borrowed handle which can be null,
// so increment refcount if p is not null
// (xincref just does nothing in this case)
template <class T>
inline T* manage_ptr(detail::borrowed<null_ok<T> >* p, int)
{
  return python::xincref((T*)p);
}

// the same - as stated in the doc, null_ok and borrowed are commutative
template <class T>
inline T* manage_ptr(null_ok<detail::borrowed<T> >* p, int)
{
  return python::xincref((T*)p);
}


// this is a borrowed handle which cannot be null, so make sure p is not null
// and increment refcount.
template <class T>
inline T* manage_ptr(detail::borrowed<T>* p, long)
{
  return python::incref(expect_non_null((T*)p));
}

// p is not borrowed and can be null - do nothing.
template <class T>
inline T* manage_ptr(null_ok<T>* p, long)
{
  return (T*)p;
}

// p is not borrowed and cannot be null - make sure it isn't null indeed.
template <class T>
inline T* manage_ptr(T* p, ...)
{
  return expect_non_null(p);
}

null_ok<T>不需要完成此代码的编译,因此它只是声明,未定义。完成它只会为编译器增加额外的工作。