氧抱怨递归c++类

Doxygen complains about recursive C++ class

本文关键字:c++ 递归      更新时间:2023-10-16

我有一个简单的递归模板,实现(优化版本)欧几里得算法。氧抱怨它:

/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 >!

我很惊讶为什么那是一个抱怨/警告。我认为递归类型是常见且合法的。它也是众多递归模板之一,但氧唯一抱怨的一个。令我惊讶的是,我只发现了类似的问题,氧错误地检测递归。

如果您感兴趣,下面是代码:

/**
 * 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};
};

这个结构确实超出了oxygen的解析能力。

由于该类的用户不关心它是否以递归方式实现,因此您可以使用以下解决方案:

/**
 * 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};
};

事先声明模板会有什么不同吗?在定义时,唯一可能的基类确实是递归的。我将这样组织代码,不仅是为了让氧原子高兴,而且因为我还首先与基本情况建立了数学归纳法和递归关系:

// 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>
{
};

默认情况下,氧没有完整的c++解析器。因此,它可能会使有效的c++代码出错。

从氧1.8.4开始,可以配置氧来使用Clang中的c++解析器,这应该可以解析大多数实际的c++代码。