如何使用 Doxygen 记录"enable_if"函数
How to document "enable_if" functions with Doxygen
在类Foo
中,我有以下模板函数:
class Foo
{
public:
template <typename T>
static typename boost::enable_if<boost::is_abstract<T>, T*>::type allocate();
template <typename T>
static typename boost::disable_if<boost::is_abstract<T>, T*>::type allocate();
};
有两个声明,但对于用户来说,只有一个函数。
用Doxygen记录此类声明的常用方法是什么
想法#1:
class Foo
{
public:
/** brief This function throws a runtime error */
template <typename T>
static typename boost::enable_if<boost::is_abstract<T>, T*>::type allocate();
/** brief This function allocates an instance of the given type */
template <typename T>
static typename boost::disable_if<boost::is_abstract<T>, T*>::type allocate();
};
想法#2:
class Foo
{
public:
/** brief This function allocates an instance of the given type if not abstract, throws an exception instead */
template <typename T>
static typename boost::enable_if<boost::is_abstract<T>, T*>::type allocate();
template <typename T>
static typename boost::disable_if<boost::is_abstract<T>, T*>::type allocate();
};
我会用std::enable_if
来回答这个问题,但它应该和boost::enable_if
一样好用。
无论Doxygen是否在运行,您都可以使用包装enable_if
的宏并以不同的方式定义它们。
在您的Doxyfile中,将以下内容添加到您的配置中:
PREDEFINED = GENERATING_DOXYGEN
EXPAND_AS_DEFINED = ENABLE_IF
ENABLED_TYPE
在C++项目中,定义以下宏:
#ifdef GENERATING_DOXYGEN
#define ENABLE_IF(cond)
#define ENABLED_TYPE(T, cond) T
#else
#define ENABLE_IF(cond) typename std::enable_if<(cond)>::type
#define ENABLED_TYPE(T, cond) typename std::enable_if<(cond), T>::type
#endif
然后,您可以按如下方式使用宏:
class Foo
{
public:
/** brief Throws a runtime error
tparam T An abstract type
detail Only participates in overload resolution
when std::is_abstract<T>::value==true */
template <typename T>
static ENABLED_TYPE(T*, std::is_abstract<T>::value) allocate();
/** brief Allocates an instance of the given type
tparam T A concrete type
detail Only participates in overload resolution
when std::is_abstract<T>::value==false */
template <typename T>
static ENABLED_TYPE(T*, !std::is_abstract<T>::value) allocate();
};
当Doxygen运行时,ENABLED_TYPE
宏将扩展到未修饰的返回类型(在您的情况下为T*
)。编译时,宏将扩展到std::enable_if<cond, T>::type
以执行SFINAE。
您可能希望将宏命名为REQUIRES
,而不是ENABLE_IF
,以提高代码的可读性。您可能还想在宏前面加上项目名称,以避免与其他库中或任何超级项目中定义的宏发生冲突。
您还可以使用一个公共函数,然后对您的两种情况使用标记调度:
class Foo
{
public:
/** brief Allocates an instance of the given type
tparam T Must be a concrete type (checked at run time) */
template <typename T>
static T* allocate()
{
do_allocate(std::is_abstract<T>());
// ...
}
private:
template <typename T>
T* do_allocate(std::false_type)
{
return new T;
}
template <typename T>
T* do_allocate(std::true_type)
{
throw std::runtime_error("T must be concrete");
}
};
使用C++17,您可以简单地执行if constexpr
:
class Foo
{
public:
/** brief Allocates an instance of the given type
tparam T Must be a concrete type (checked at run time) */
template <typename T>
static T* allocate()
{
if constexpr (std::is_abstract<T>())
{
throw std::runtime_error("T must be concrete");
}
else
{
return new T;
}
}
};
相关文章:
- Insert函数不适用于2 if语句C++
- Fmod 函数清楚地输出一个预期的双精度值,但 if(fmod == 预期的双精度值)的计算结果不是 true
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取
- 在 if 语句中调用重载构造函数失败
- 为什么当 while 循环中的 if 条件变为 false 时,我的函数不输出最后一条语句?
- 简化 if 流函数的 while 循环中的大量 while 循环
- 在 constexpr-if 条件下比较 constexpr 函数参数会导致错误
- if-else 与三元函数调用性能
- 函数如何在不这样做的情况下在新线程上运行"as if"?
- 无法编译包含"if constexpr"的函数模板实例化
- 性能:否则如果 vs if 在已经返回的函数中
- 重构模板函数中的常量表达式 if 语句
- if, else if, else 函数未准确显示结果
- 为什么 if 语句对于运算符重载函数计算 false
- 使用 if/else if 的函数输出问题
- 'if constexpr branch'不会在模板函数内的 lambda 中被丢弃
- C++在if函数中添加变量
- Visual Studio似乎忽略了我的IF函数
- 更简单的方法来写这个if函数c++
- SDL c++: if函数不工作.编译精细-逻辑错误