C++ 代码复制和模板专门化(当专门化函数具有不同的返回类型时)
我正在创建一个模板类C++ 代码复制和模板专门化(当专门化函数具有不同的返回类型时),c++,templates,template-specialization,C++,Templates,Template Specialization,我正在创建一个模板类D,其中包含一个方法(在本例中为操作符()),该方法根据N的值返回不同的类型 我只能通过创建两个独立的类声明来实现这一点,但这是以大量代码重复为代价的。我还试图创建一个公共基类来将公共内容放入其中,但我无法让构造函数正确继承,也不知道这会有多习惯 #include <cstdio> template <int N> struct D{ int s; D(int x):s(x){} int yell(int x){
D
,其中包含一个方法(在本例中为操作符()),该方法根据N的值返回不同的类型
我只能通过创建两个独立的类声明来实现这一点,但这是以大量代码重复为代价的。我还试图创建一个公共基类来将公共内容放入其中,但我无法让构造函数正确继承,也不知道这会有多习惯
#include <cstdio>
template <int N>
struct D{
int s;
D(int x):s(x){}
int yell(int x){
printf("N=%d, %d\n", N, s+x);
return s+x;
}
D<N-1> operator()(int x){
D<N-1> d(yell(x));
return d;
}
};
template <>
struct D<1>{
int s;
D(int x): s(x){}
int yell(int x){
printf("N=%d, %d\n", 1, s+x);
return s+x;
}
int operator()(int x){
return yell(x);
}
};
int main()
{
D<2> f(42);
printf("%d\n", f(1)(2));
return 0;
}
#包括
模板
结构D{
int-s;
D(intx):s(x){}
int-yell(int-x){
printf(“N=%d,%d\N”,N,s+x);
返回s+x;
}
D运算符()(int x){
D(yell(x));
返回d;
}
};
模板
结构D{
int-s;
D(intx):s(x){}
int-yell(int-x){
printf(“N=%d,%d\N”,1,s+x);
返回s+x;
}
int运算符()(int x){
回叫(x);
}
};
int main()
{
D f(42);
printf(“%d\n”,f(1)(2));
返回0;
}
如何使代码更美观?您可以使用奇怪的重复模板模式
template<int N, template<int> typename D> struct d_inner {
D<N-1> operator()(int x) {
return D<N-1>(static_cast<D<N>*>(this)->yell(x));
}
};
template<template<int> typename D> struct d_inner<1, D> {
int operator()(int x) {
return static_cast<D<1>*>(this)->yell(x);
}
};
template <int N> struct D : public d_inner<N, D> {
int s;
D(int x):s(x){}
int yell(int x){
printf("N=%d, %d\n", N, s+x);
return s+x;
}
};
模板结构d\u内部{
D运算符()(int x){
返回D(静态施法(this)->yell(x));
}
};
模板结构d_内部{
int运算符()(int x){
返回static_cast(this)->yell(x);
}
};
模板结构D:公共D_内部{
int-s;
D(intx):s(x){}
int-yell(int-x){
printf(“N=%d,%d\N”,N,s+x);
返回s+x;
}
};
我并没有看到这个特定对象被模板化的实用性或目的,它可能很难做到。我不确定它是否更好看:但它避免了源代码重复:
// Find a name for this ...
template<int N, template<int M> class X>
struct foo {
typedef X<N> type;
};
template< template<int M> class X >
struct foo<0,X> {
typedef int type;
};
template <int N>
struct D{
int s;
D(int x):s(x){}
int yell(int x){
printf("N=%d, %d\n", N, s+x);
return s+x;
}
typename foo<N-1,D>::type
operator()(int x){
return typename foo<N-1,D>::type(yell(x));
}
};
//查找此文件的名称。。。
模板
结构foo{
类型def X类型;
};
模板<模板类X>
结构foo{
typedef int类型;
};
模板
结构D{
int-s;
D(intx):s(x){}
int-yell(int-x){
printf(“N=%d,%d\N”,N,s+x);
返回s+x;
}
typename foo::type
运算符()(int x){
返回typename foo::type(yell(x));
}
};
您需要重新考虑返回类型的实用性是否取决于参数的值。要么使其成为一致的多态返回类型,要么找出一种明智的方法始终返回基本类型。在这种情况下,我通常会发现返回到应用程序的基本需求是有帮助的,问题是没有一种好的类型来编码特定长度的列表。使用模板黑魔法可以让我的小DSL使用起来很好,并且类型安全。所以你需要一些“编译时长度”的链表吗?std::array/boost::array不适合您的情况吗?缺点是,您不能从中获取“子数组”对象,但也可以使用“运行时可变长度接口”(迭代器,[],指针…)。+1表示“我看不到模板化此特定对象的实用程序或目的,但很容易无法”