Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 没有定义的结构模板的用途是什么?_C++_Templates_Metaprogramming_Boost Python - Fatal编程技术网

C++ 没有定义的结构模板的用途是什么?

C++ 没有定义的结构模板的用途是什么?,c++,templates,metaprogramming,boost-python,C++,Templates,Metaprogramming,Boost Python,下面是Boost.Python的一个片段: template struct null_ok;//工作怎么样? 模板 内联空值\u确定*允许空值(T*p) { 返回(null_ok*)p; } 有一种说法是,对于前向声明的结构,null\u ok没有定义,null\u ok与模板参数T没有任何关系 在中,给出了以下提示: 句柄y(null\u ok(x))允许y变为null 句柄y(x),其中x不是null的结果。\u ok,永远不会导致null y。如果x为NULL,将引发异常 我无法理解结构

下面是Boost.Python的一个片段:

template struct null_ok;//工作怎么样?
模板
内联空值\u确定*允许空值(T*p)
{
返回(null_ok*)p;
}
有一种说法是,对于前向声明的结构,
null\u ok
没有定义,
null\u ok
与模板参数
T
没有任何关系

在中,给出了以下提示:

句柄y(null\u ok(x))允许y变为null

句柄y(x),其中x不是null的结果。\u ok,永远不会导致null y。如果x为NULL,将引发异常


我无法理解结构模板的声明(没有定义)是如何实现上述目的的?

与代码片段(我的注释)下方的
handle.hpp
中的代码完全一致:

//这是借用的句柄,可以为null,
//因此,如果p不为null,则增加refcount
//(xincref在这种情况下什么都不做)
模板
内联T*manage\u ptr(细节::借用*p,int)
{
返回python::xincref((T*)p);
}
//相同-如文档中所述,null_ok和followed是可交换的
模板
内联T*manage\u ptr(null\u ok*p,int)
{
返回python::xincref((T*)p);
}
//这是一个借用的句柄,不能为null,因此请确保p不为null
//和增量refcount。
模板
内联T*管理ptr(细节::借用*p,长)
{
返回python::incref(期望非空((T*)p));
}
//p不是借来的,可以为空-不做任何事情。
模板
内联T*manage\u ptr(null\u ok*p,长)
{
返回(T*)p;
}
//p不是借用的,不能为null-确保它确实不是null。
模板
内联T*管理ptr(T*p,…)
{
返回expect_non_null(p);
}
null\u ok
编译此代码不需要完整,因此它只是声明的,而不是定义的。完成它只会为编译器增加额外的工作。

关键是要将“这个指针为null没问题”与指针本身的原始类型一起编码

然后,接受指针的函数模板可以重载以识别
null\u ok*
指针,而不会在null指针上出错(同时将其转换回
T*


您不需要定义
null\u ok
,因为您可以有指向不完整类型的指针,它可以防止人们意外地编写类似
null\u ok a

谢谢你的评论,马克。我当然知道
转发声明
。然而,这个声明没有定义。我认为它有一些元编程的目的,但我不知道那是什么。@Marglisseyes,前一个标题令人困惑。编辑@马尔基里斯
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;
}
// 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);
}