#include "vector"
template <unsigned int order>
struct ReturnType;
template <>
struct ReturnType<0>
{
using type = double; // Return type for value
};
template <>
struct ReturnType<1>
{
using type = std::vector<double>; // Return type for deriv
};
template <unsigned int dim>
class Function
{
void value(typename ReturnType<0>::type &value) {};
void deriv(typename ReturnType<1>::type &deriv) {};
};
int main() {
Function<1> interp;
return 0;
}
I want to write a Function
class and the arguments of the member functions are specializations of a ReturnType<order>
struct. The idea is that when I implement multiple derived classes, I only have to change the return types at one place in the code. However I prefer to place the ReturnType<order>
struct as public type in the Function
class to enhance encapsulation.
Conceptually:
#include <vector>
template <unsigned int dim>
class Function
{
public:
template <unsigned int order>
struct ReturnType;
using ValueReturnType = typename ReturnType<0>::type;
using DerivReturnType = typename ReturnType<1>::type;
void value(ValueReturnType &value) {};
void deriv(DerivReturnType &deriv) {};
};
template <>
template <>
struct Function<1>::ReturnType<0>
{
using type = double;
};
template <>
template <>
struct Function<1>::ReturnType<1>
{
using type = std::vector<double>;
};
int main() {
return 0;
}
This solution requires full template specialization as specializations without the class template are not allowed (correct me if I am wrong).
Is there a solution without full template specialization and keeping the ReturnType
struct in the Function
class?
2
I don’t think you can, because in order to name the nested type you must instantiate the nesting type, which you can’t because it depends on the nested one.
What you can do is move one or both types into a separate namespace. Usually one uses namespace detail
for this with the implied meaning that outside users are not supposed to access anything from detail::
.