c++ - 模板互递归

标签 c++ templates recursion libraries

我想在我的库中有一个模板函数 func这样用户就可以用自己的类型重载它。问题是我的类型系统是这样的

T := A<T>, B<T>, C

因此,template<class T> void func(A<T>);需求template<class T> void func(B<T>);如果它专门用于 T = B<C> .相反,如果我们实例化 func(B<T>)T = A<C> , B<T>特化需要 A<T>特化。

到这里为止的问题可以通过在一些通用头文件中声明模板函数来解决。

我不知道如何处理的是如何使这种类型系统可扩展。我希望用户可以定义自己的类型 template<class T> class D<T>;并实现她自己的 template<class T> void func(D<T>); .在这种情况下,我不知道用户如何转发声明她的类型,以便在特化中 A<D<C>>函数void func(A<T>);能够找到void func(D<T>); .

有什么标准的方法可以做到这一点吗?

编辑问题的最小工作示例:

//在A.hpp中

namespace ns {
template<class T> struct A { T t; };
template<class T>
void fun (A<T> a) { fun(a.t); }
}

//B.hpp

namespace ns {
template<class T> struct B { T t; };
template<class T>
void fun (B<T> b) { fun(b.t); }

//C.hpp

#include <iostream>
namespace other {
template<class T>
struct C {};
}

namespace ns {
template<class T>
void fun(other::C<T> c) { std::cout << "C" << std::endl; }
}

// main.cpp

#include "A.hpp"
#include "B.hpp"
#include "C.hpp"

namespace ns {
void f () {
    fun(A<B<other::C<int>>>());
}
}


int main () {
    ns::f();
}

此示例无法编译。如果我们对 main.cpp 中的包含重新排序,它就会编译。作为

#include "C.hpp"
#include "B.hpp"
#include "A.hpp"

现在,这显然是一个 hack。使用此设计,用户将无法同时实例化 A<B<C<int>>>。和 B<A<C<int>>> .一个解决方案是转发声明 AB在其他一些模板中并将其包含在 A.hpp 中和 B.hpp .当您尝试让库的用户定义她自己的类型时,问题就来了。如果图书馆的用户定义了她自己的类型 template<class T> class D; ,她不能转发声明,然后,如果她尝试实例化 A<D<C<int>>> , 编译会失败。

在此示例中,命名空间 other表示我无法控制的命名空间,C代表某个其他库中预先存在的类。这可以被认为是一些 boost类或类似的。 ns namespace 是我的库定义的 namespace 。

最佳答案

如果 fun() 是模板类中的静态方法呢?

所以你可以部分特化这个类?

我的意思是类似

//000.h

#ifndef h_000__h
#define h_000__h

namespace ns
 {
   template <typename T>
   struct foo;
 }

#endif

//001.h

#ifndef h_001__h
#define h_001__h

#include <iostream>

#include "000.h"

namespace ns
 {
   template<class T>
   struct A
    { T t; };

   template <typename T>
   struct foo<A<T>>
    {
      static void fun (A<T> a)
       { std::cout << "A<T> fun" << std::endl; foo<T>::fun(a.t); }
    };
 }

#endif

//002.h

#ifndef h_002__h
#define h_002__h

#include <iostream>

#include "000.h"

namespace ns
 {
   template <typename T>
   struct B
    { T t; };

   template <typename T>
   struct foo<B<T>>
    {
      static void fun (B<T> a)
       { std::cout << "B<T> fun" << std::endl; foo<T>::fun(a.t); }
    };
 }

#endif

//003.h

#ifndef h_003__h
#define h_003__h

#include <iostream>

#include "000.h"

namespace other
 {
   template <typename T>
   struct C
    { };
 }

namespace ns
 {
   template <typename T>
   struct foo<other::C<T>>
    {
      static void fun (other::C<T> a)
       { std::cout << "C<T> fun" << std::endl; }
    };
 }

#endif

// main.cpp

#include "001.h"
#include "002.h"
#include "003.h"

namespace ns
 {
   void f ()
    {
      using type = A<B<other::C<int>>>;

      foo<type>::fun(type{});
    }
 }

int main ()
 {
   ns::f(); // print A<T> fun \n B<T> fun \n C<T> fun \n
 }

关于c++ - 模板互递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46734122/

相关文章:

c++ - 如何将模板存储为典型 C++ 类的成员

c++ - 模板化双模板类方法

C++ 为模板类调用模板化构造函数

asynchronous - Kotlin 挂起函数递归调用

c++ - 如何在不使用变量的情况下启用 Boost Program Options 中的其他选项?

C++ 堆栈和二维数组

c++ - 如何将 GCC 诊断编译指示与 C++ 模板函数一起使用?

python - 在python中递归退出矩形

python - 使用递归查找 Python 列表中的第 K 个最大元素

c++ - 分配用 new 声明的 vector 中的元素。 C++