如何为想要公开相互递归函数的仅标头库组织包含

How to organize includes for a header-only library that wants to expose mutually recursive functions?

本文关键字:包含 递归函数      更新时间:2023-10-16

我正在创建一个库,以便有如下所示的函数:

template <typename T> bool A (int, int, T&);
template <typename T> bool B (int, int, T&);
template <typename T> 
class IFoo {
    virtual T funct(int i) = 0;
};
template <typename T>
class FooA : IFoo<T> {
    virtual T funct(int i) override {
        if (!i) {
            return FooB(i-1);
        } else {
            return T(0);
        }
    }
};
template <typename T>
class FooB : IFoo<T> {
    virtual T funct(int i) override {
        if (!i) {
            return FooA(i-1);
        } else {
            return T(1);
        }
    }
};

这些定义需要将代码拆分为声明和定义部分,以便允许两个过程相互了解,然后同时访问实现。

但我的问题是,我如何

以清晰的方式公开这些函数(意思是,我应该如何编写一个标头来封装依赖包含模式(,同时还可以轻松添加新的"函数"或其他相互递归的组件(含义、函数或派生类(,以便组件的用户不必手动订购声明标头和定义标头的包含?

通过将声明与实现分开。

template <typename T>
class IFoo {
    virtual T funct(int i) = 0;
};
template <typename T>
class FooA : IFoo<T> {
    virtual T funct(int i) override;  // declaration only...
};
template <typename T>
class FooB : IFoo<T> {
    virtual T funct(int i) override {
        if (!i) {
            return FooA<T>(i-1);
        } else {
            return T(1);
        }
    }
};

// implementation here - once all type information is available
template<typename T>
T FooA<T>::funct(int i) {
    if (!i) {
        return FooB<T>(i-1);
    } else {
        return T(0);
    }
}

如何组织标题?

这是一种方法:

detail/ifoo.hpp

#pragma once
template <typename T>
class IFoo {
    virtual T funct(int i) = 0;
};

detail/fooa.hpp

#pragma once
#include "ifoo.hpp"
template <typename T>
class FooA : IFoo<T> {
    virtual T funct(int i) override;
};

detail/foob.hpp

#pragma once
#include "ifoo.hpp"
template <typename T>
class FooB : IFoo<T> {
    virtual T funct(int i) override;
};

细节/impl_fooa.hpp

#pragma once
#include "fooa.hpp"
#include "foob.hpp"
template<typename T>
T FooA<T>::funct(int i) {
    if (!i) {
        return FooB<T>(i-1);
    } else {
        return T(0);
    }
}

细节/impl_foob.hpp

#pragma once
#include "fooa.hpp"
#include "foob.hpp"
template<typename T>
virtual T FooB<T>::funct(int i) override {
    if (!i) {
        return FooA<T>(i-1);
    } else {
        return T(1);
    }
}

最后你的标题

图书馆.hpp

#pragma once
#include "detail/ifoo.hpp"
#include "detail/fooa.hpp"
#include "detail/foob.hpp"
#include "detail/impl_fooa.hpp"
#include "detail/impl_foob.hpp"

将强连接的组件放在一个标头中。