我想在我的库中有一个模板函数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"
现在,这显然是一个黑客它只是编译。使用这种设计,用户将不能实例化A<B<C<int>>>
和B<A<C<int>>>
。解决方案是在其他模板中转发声明A
和B
,并将其包含在A.hpp
和B.hpp
中。当您尝试让库的用户定义自己的类型时,问题就出现了。如果库的用户定义了自己的类型template<class T> class D;
,她不能转发声明,然后,如果她尝试实例化A<D<C<int>>>
,则编译将失败。
在这个例子中,命名空间other
代表一个名字空间,我没有控制权,并且C
表示在其他一些库中的预先存在的类。这可以被认为是一些boost
类或类似的。命名空间ns
是我的库定义的名称空间。
请出示一些实际的代码。 –
我可以猜出你的意思是“表格”,但我很容易出错。草拟该想法的实际代码摆脱了许多不明确之处。 'T:= A'至少在同一陈述中滥用了一个重复使用的'T'来表示两个不同的事物,而且我不确定这个逗号是否表明了一些奇怪的回忆,或者它只是一个'T '可以。通过编辑显示你的计划的问题的实际代码(这个代码应该编译) –
Yakk
通过':='我打算为术语'T'定义一个语法。 我想在一个简短的例子中复制这种行为,代码编译依赖于包含的顺序。 – Lezkus