Doxygen 抱怨递归 C++ class
Doxygen complains about recursive C++ class
我有一个实现欧几里德算法(优化版本)的简单递归模板。 Doxygen 抱怨它:
/usr/home/kamikaze/stark/Yggdrasil/src/units/Units.hpp:335: warning: Detected potential recursive class relation between class units::euclid and base class units::euclid< Rhs, Lhs%Rhs >!
/usr/home/kamikaze/stark/Yggdrasil/src/units/Units.hpp:335: warning: Detected potential recursive class relation between class units::euclid and base class euclid< Rhs, Lhs%Rhs >!
/usr/home/kamikaze/stark/Yggdrasil/src/units/Units.hpp:335: warning: Detected potential recursive class relation between class units::euclid and base class units::euclid< Rhs, Lhs%Rhs >!
/usr/home/kamikaze/stark/Yggdrasil/src/units/Units.hpp:335: warning: Detected potential recursive class relation between class units::euclid and base class euclid< Rhs, Lhs%Rhs >!
我傻眼了,为什么那是 complaint/warning。我认为递归类型是常见且合法的。它也是许多递归模板之一,但唯一一个 doxygen 抱怨。
令我惊讶的是,我只发现了 doxygen 错误检测递归的类似问题。
如果你有兴趣,这里是代码:
/**
* Implements Euclid's algorithm to find the GCD between two integers.
*
* @tparam Lhs,Rhs
* The values to get the GCD for
*/
template <int Lhs, int Rhs>
struct euclid : euclid<Rhs, Lhs % Rhs> {
};
/**
* Terminates Euclid's algorithm.
*
* @tparam Gcd
* The GCD to return
* @see euclid
*/
template <int Gcd>
struct euclid<Gcd, 0> {
/**
* The GCD of the two original values.
*/
static constexpr int const value{Gcd};
};
这个构造确实超出了 doxygen 的解析能力。
由于此 class 的用户没有兴趣知道它是以递归方式实现的,您可以使用以下解决方法:
/**
* Implements Euclid's algorithm to find the GCD between two integers.
*
* @tparam Lhs,Rhs
* The values to get the GCD for
*/
template <int Lhs, int Rhs>
struct euclid /** @cond */ : euclid<Rhs, Lhs % Rhs> /** @endcond */ {
/** @cond */
};
template <int Gcd>
struct euclid<Gcd, 0> {
/** @endcond
* The GCD of the two original values.
*/
static constexpr int const value {Gcd};
};
默认情况下,doxygen 没有完整的 C++ 解析器。所以它可能会得到错误的有效 C++ 代码。
因为 doxygen 1.8.4 it is possible to configure doxygen 使用来自 Clang 的 C++ 解析器,它应该可以解析大部分真实世界的 C++ 代码。
事先声明模板会有什么不同吗?在定义点上,唯一可能的基础 class 确实是递归的。我会这样组织代码,不仅是为了让 Doxygen 高兴,还因为我还首先与基本情况建立了数学归纳和递归关系:
// forward declaration
template <int Lhs, int Rhs>
struct euclid;
// base case
template <int Gcd>
struct euclid<Gcd, 0>
{
static constexpr int const value{Gcd};
};
// recurrence relation
template <int Lhs, int Rhs>
struct euclid : euclid<Rhs, Lhs % Rhs>
{
};
我有一个实现欧几里德算法(优化版本)的简单递归模板。 Doxygen 抱怨它:
/usr/home/kamikaze/stark/Yggdrasil/src/units/Units.hpp:335: warning: Detected potential recursive class relation between class units::euclid and base class units::euclid< Rhs, Lhs%Rhs >!
/usr/home/kamikaze/stark/Yggdrasil/src/units/Units.hpp:335: warning: Detected potential recursive class relation between class units::euclid and base class euclid< Rhs, Lhs%Rhs >!
/usr/home/kamikaze/stark/Yggdrasil/src/units/Units.hpp:335: warning: Detected potential recursive class relation between class units::euclid and base class units::euclid< Rhs, Lhs%Rhs >!
/usr/home/kamikaze/stark/Yggdrasil/src/units/Units.hpp:335: warning: Detected potential recursive class relation between class units::euclid and base class euclid< Rhs, Lhs%Rhs >!
我傻眼了,为什么那是 complaint/warning。我认为递归类型是常见且合法的。它也是许多递归模板之一,但唯一一个 doxygen 抱怨。 令我惊讶的是,我只发现了 doxygen 错误检测递归的类似问题。
如果你有兴趣,这里是代码:
/**
* Implements Euclid's algorithm to find the GCD between two integers.
*
* @tparam Lhs,Rhs
* The values to get the GCD for
*/
template <int Lhs, int Rhs>
struct euclid : euclid<Rhs, Lhs % Rhs> {
};
/**
* Terminates Euclid's algorithm.
*
* @tparam Gcd
* The GCD to return
* @see euclid
*/
template <int Gcd>
struct euclid<Gcd, 0> {
/**
* The GCD of the two original values.
*/
static constexpr int const value{Gcd};
};
这个构造确实超出了 doxygen 的解析能力。
由于此 class 的用户没有兴趣知道它是以递归方式实现的,您可以使用以下解决方法:
/**
* Implements Euclid's algorithm to find the GCD between two integers.
*
* @tparam Lhs,Rhs
* The values to get the GCD for
*/
template <int Lhs, int Rhs>
struct euclid /** @cond */ : euclid<Rhs, Lhs % Rhs> /** @endcond */ {
/** @cond */
};
template <int Gcd>
struct euclid<Gcd, 0> {
/** @endcond
* The GCD of the two original values.
*/
static constexpr int const value {Gcd};
};
默认情况下,doxygen 没有完整的 C++ 解析器。所以它可能会得到错误的有效 C++ 代码。
因为 doxygen 1.8.4 it is possible to configure doxygen 使用来自 Clang 的 C++ 解析器,它应该可以解析大部分真实世界的 C++ 代码。
事先声明模板会有什么不同吗?在定义点上,唯一可能的基础 class 确实是递归的。我会这样组织代码,不仅是为了让 Doxygen 高兴,还因为我还首先与基本情况建立了数学归纳和递归关系:
// forward declaration
template <int Lhs, int Rhs>
struct euclid;
// base case
template <int Gcd>
struct euclid<Gcd, 0>
{
static constexpr int const value{Gcd};
};
// recurrence relation
template <int Lhs, int Rhs>
struct euclid : euclid<Rhs, Lhs % Rhs>
{
};