问题
Is it possible to access values of non-type template parameters in specialized template class?
If I have template class with specialization:
template <int major, int minor> struct A {
void f() { cout << major << endl; }
}
template <> struct A<4,0> {
void f() { cout << ??? << endl; }
}
I know it the above case it is simple to hardcode values 4 and 0 instead of using variables but what I have a larger class that I'm specializing and I would like to be able to access the values.
Is it possible in A<4,0> to access major
and minor
values (4 and 0)? Or do I have to assign them on template instantiation as constants:
template <> struct A<4,0> {
static const int major = 4;
static const int minor = 0;
...
}
回答1:
This kind of problem can be solved by having a separate set of "Traits" structs.
// A default Traits class has no information
template<class T> struct Traits
{
};
// A convenient way to get the Traits of the type of a given value without
// having to explicitly write out the type
template<typename T> Traits<T> GetTraits(const T&)
{
return Traits<T>();
}
template <int major, int minor> struct A
{
void f()
{
cout << major << endl;
}
};
// Specialisation of the traits for any A<int, int>
template<int N1, int N2> struct Traits<A<N1, N2> >
{
enum { major = N1, minor = N2 };
};
template <> struct A<4,0>
{
void f()
{
cout << GetTraits(*this).major << endl;
}
};
回答2:
Not really an answer to your question, but you could enumerate them, viz:
enum{
specialisationMajor=4,
specialisationMinor=0
};
template <> struct A<specialisationMajor,specialisationMinor> {
static const int major = specialisationMajor;
static const int minor = specialisationMinor;
...
}
回答3:
Not really an answer to your question, but the idea below helped me once:
#include <iostream>
template <int major, int minor, int= major, int= minor> struct A {
void f() { std::cout << major << '\n'; }
};
template <int major, int minor> struct A<major, minor, 4, 0> {
void f() { std::cout << major << ':' << minor << '\n'; }
};
int main()
{
A<3, 3>().f();
A<4, 0>().f();
}
回答4:
No, you don't have access to the specialized non-type template parameters. But here is a way to not repeat yourself in the implementation of f
:
template <int major, int minor>
struct f_impl
{
void f() { cout << major << endl; }
};
template <int major, int minor>
struct A : public f_impl<major, minor>
{};
template <> struct A<4,0> : public f_impl<4,0>
{};
For this example, one doesn't gain all too much, as one needs to write the 4,0
twice (--so you could write it as well a second time in the cout
in your OP). But it starts to pay out if you have more functions using the template parameters.
来源:https://stackoverflow.com/questions/1162401/is-it-possible-to-access-values-of-non-type-template-parameters-in-specialized-t