Estoy creando una clase de plantilla D<N>
, con un método (operador(), en este caso) que devuelve diferentes tipos, dependiendo del valor de N.Duplicación de código y especialización de plantilla (cuando la función especializada tiene diferentes tipos de retorno)
Solo pude hacer que esto funcionara al crear dos declaraciones de clases separadas, pero esto tuvo el costo de una gran cantidad de duplicación de código. También traté de crear una clase base común de tirar las cosas en común, pero no pude conseguir el constructor para heredar la derecha y no sé cómo idiomática que sería así ...
#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;
}
Cómo ¿Puedo hacer que mi código se vea mejor?
Es necesario reconsiderar la utilidad del tipo de retorno que depende del valor de los parámetros. Haga que sea un tipo de retorno polimórfico consistente o descubra una forma sensata de devolver siempre un tipo básico. En situaciones como esta, generalmente me resulta útil volver a las necesidades básicas de la aplicación. – wallyk
El problema es que no hay un buen tipo para codificar listas de cierta longitud. Hacer la magia negra de plantilla permitiría que mi pequeña DSL fuera agradable de usar y también segura. – hugomg
¿Necesita una lista vinculada de "compilación de la duración del tiempo"? ¿No es std :: array/boost :: array adecuado para su caso? La desventaja es que no puede tomar un objeto de "subcampo", pero también puede usar la "interfaz de longitud variable de tiempo de ejecución" (iteradores, [], puntero ...). – ysdx