Home » Extra libraries, Code snippets, applications etc. » C++ language problems and code snippets » Nested template question
Nested template question [message #51842] |
Sun, 09 June 2019 16:16 |
|
koldo
Messages: 3394 Registered: August 2008
|
Senior Veteran |
|
|
Hi all
I wanted to overload a function to get a zero (it is a sample):
void test() {
double val = GetAZero<double>();
std::complex<float> valc1 = GetAZero<std::complex<float>>();
std::complex<double> valc1 = GetAZero<std::complex<double>>();
}
This code works, but it is not nice:
template <class T> T GetAZero() {return 0;}
template <> std::complex<float> GetAZero() {return std::complex<float> (0, 0);}
template <> std::complex<double> GetAZero() {return std::complex<double>(0, 0);}
This code is more compact, but it does not work:
template <class T> T GetAZero() {return 0;}
template <class std::complex<T>> std::complex<T> GetAZero() {return std::complex<T> (0, 0);}
Is there an adequate way to do this?
Best regards
Iñaki
|
|
|
|
Re: Nested template question [message #51869 is a reply to message #51868] |
Mon, 10 June 2019 21:40 |
|
koldo
Messages: 3394 Registered: August 2008
|
Senior Veteran |
|
|
Thank you Novo
Nice hack... the problem is that my code is already inside a class, so GetAZero() is really a class function
To solve this, the inner class should have to point the outer class, maybe passing a pointer in the inner class constructor, but then the hack is getting more complex.
Best regards
Iñaki
[Updated on: Mon, 10 June 2019 21:41] Report message to a moderator
|
|
|
Re: Nested template question [message #51871 is a reply to message #51869] |
Mon, 10 June 2019 23:48 |
Novo
Messages: 1371 Registered: December 2006
|
Ultimate Contributor |
|
|
I don't really get what you need to do.
If it is just setting any class to zero, as in your example, then you do not need method GetAZero(). Class AZero will work out of the box.
If you are trying to specialize your template method for all possible variants of std::complex<T>, then this is called partial template specialization, and it works only for classes. You need to create a dummy class and partially specialize it.
template <typename T>
struct dummy {
T DoIt() const { return T(); }
};
template <typename T>
struct dummy<std::complex<T>> {
using PT = std::complex<T>;
PT DoIt() const { return PT(0, 0); }
};
struct Boo {
Boo() {
double val = GetAZero<double>();
std::complex<float> valc1 = GetAZero<std::complex<float>>();
std::complex<double> valc2 = GetAZero<std::complex<double>>();
}
template <class T>
T GetAZero() { return dummy<T>().DoIt(); }
};
Regards,
Novo
|
|
|
|
Re: Nested template question [message #52225 is a reply to message #51842] |
Mon, 12 August 2019 09:56 |
slashupp
Messages: 231 Registered: July 2009
|
Experienced Member |
|
|
Don't know if I understand the problem correctly,
but I came up with the following:
#include <iostream>
#include <complex>
template<typename...P> void say(P...p){ (std::cout << ... << p); }
template<typename T> T mkZero(T &t) { t=T(0); return t; }
template<typename T, typename...V> T mkVal(T &t, V...v) { t=T(v...); return t; }
int main()
{
int i;
float f;
double d;
std::complex<int> ci;
std::complex<float> cf;
std::complex<double> cd;
mkVal(i, 11);
mkVal(f, 22.22);
mkVal(d, 33);
mkVal(ci, 44, 44);
mkVal(cf, 5.5, 55.55);
mkVal(cd, 66, 66.6);
say("valued: i=", i, ", f=", f, ", d=", d, ", ci=", ci, ", cf=", cf, ", cd=", cd, "\n");
mkZero(i);
mkZero(f);
mkZero(d);
mkZero(ci);
mkZero(cf);
mkZero(cd);
say("zeroed: i=", i, ", f=", f, ", d=", d, ", ci=", ci, ", cf=", cf, ", cd=", cd, "\n");
return 0;
}
Output:
valued: i=11, f=22.22, d=33, ci=(44,44), cf=(5.5,55.55), cd=(66,66.6)
zeroed: i=0, f=0, d=0, ci=(0,0), cf=(0,0), cd=(0,0)
|
|
|
Goto Forum:
Current Time: Fri Sep 20 03:51:36 CEST 2024
Total time taken to generate the page: 0.03257 seconds
|