I'd like to specify my templated function's return type, by an other template argument. All of this inside a class.
In the header file:
class MyClass {
template<int type, typename RT>
RT myfunc();
};
In the .cpp something like this:
template<>
int MyClass::myfunc<1, int>() { return 2; }
template<>
double MyClass::myfunc<2, double>() { return 3.14; }
template<>
const char* MyClass::myfunc<3, const char*>() { return "some string"; }
And I would like to be able to use my function like this:
MyClass m;
int i = m.myfunc<1>(); // i will be 2
double pi = m.myfunc<2>(); // pi will be 3.14
const char* str = m.myfunc<3>(); // str == "some string"
So I would like my function to be able to parameterized by one template integer (or enumeration whatsoever), and the return type will be different, based on this integer.
I don't want the function to work with any other integer arguments than the specified ones, for example here m.myfunc<4>()
would give compile error.
I want to parameterize my function by one template argument only, because m.myfunc<1, int>()
would be working, but I don't want to write the typename all the time.
I tried with auto return types, or templating other way around, but always got some compile errors. (Function not found, unresolved externals...)
Is this possible in any way?
There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.
Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.
A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be constant expressions, addresses of functions or objects with external linkage, or addresses of static class members.
In template definitions, typename provides a hint to the compiler that an unknown identifier is a type. In template parameter lists, it's used to specify a type parameter.
Is this what you seek?
template<int n>
struct Typer
{
};
template<>
struct Typer<1>
{
typedef int Type;
};
template<>
struct Typer<2>
{
typedef double Type;
};
template<>
struct Typer<3>
{
typedef const char* Type;
};
class MyClass
{
public:
template<int typeCode>
typename Typer<typeCode>::Type myfunc();
};
template<> Typer<1>::Type MyClass::myfunc<1>(){ return 2; }
template<> Typer<2>::Type MyClass::myfunc<2>() { return 3.14; }
template<> Typer<3>::Type MyClass::myfunc<3>() { return "some string"; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With