With a templated number wrapping struct:
template <int I> struct Num { static const int n = I; };
and a few overloaded functions:
template <typename T>
Num<0> id(T x) { return Num<0>(); }
Num<1> id(int x) { return Num<1>(); }
Num<2> id(double x) { return Num<2>(); }
Num<3> id(char x) { return Num<3>(); }
I can initialise the m_i
member of a Zod
struct using decltype
and the type of the return argument of id
:
template <typename T>
struct Zod {
Zod(T x) { m_i = identity<decltype(id(x))>::type::n; }
int m_i;
};
However, what I'd really like is for the Zod
struct to have a second integer template argument initialised to the value which m_i
was set to.
template <typename T, int I = ?>
struct Zod { ... }
This seems possible, as the identity
/decltype
expression evaluates to a compile time constant开发者_Python百科; for example, this is fine at global scope:
char c;
static const int g = identity<decltype(id(c))>::type::n;
The problem is that the x
argument of the constructor is not available in the scope of Zod
's template declaration. Can it be done?
It's perfectly possible- just pass in *((T*)nullptr)
to obtain an lvalue of any type T regardless of it's constructability. After all, all you actually do with the constructor argument is pass it to id
and then decltype
that, which is perfectly doable in the template, since you know that the type of x
is T
.
template<typename T, int I = identity<decltype(id(*((T*)nullptr)))>::type::n> struct Zod {
...
};
精彩评论