هل من الممكن الوصول إلى قيم معلمات القالب غير من النوع في فئة القالب المتخصصة؟
-
18-09-2019 - |
سؤال
هل من الممكن الوصول إلى قيم معلمات القالب غير من النوع في فئة القالب المتخصصة؟
إذا كان لدي فئة قالب مع التخصص:
template <int major, int minor> struct A {
void f() { cout << major << endl; }
}
template <> struct A<4,0> {
void f() { cout << ??? << endl; }
}
أعلم أنه الحالة المذكورة أعلاه أنها بسيطة بالنسبة لقيم المخدرات 4 و 0 بدلا من استخدام المتغيرات ولكن ما لدي فئة أكبر وأنا متخصص وأرغب في أن أكون قادرا على الوصول إلى القيم.
هل من الممكن في الوصول إلى <4،0> major
و minor
القيم (4 و 0)؟ أو هل يجب علي تعيينها على إنشاء مثيل للمثبتين
template <> struct A<4,0> {
static const int major = 4;
static const int minor = 0;
...
}
المحلول
يمكن حل هذا النوع من المشكلة من خلال وجود مجموعة منفصلة من الهياكل "الصفات".
// 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;
}
};
نصائح أخرى
ليس حقا إجابة على سؤالك، ولكن يمكنك تعدادها، VIZ:
enum{
specialisationMajor=4,
specialisationMinor=0
};
template <> struct A<specialisationMajor,specialisationMinor> {
static const int major = specialisationMajor;
static const int minor = specialisationMinor;
...
}
ليس حقا إجابة على سؤالك، لكن الفكرة أدناه ساعدتني مرة واحدة:
#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();
}
لا، ليس لديك إمكانية الوصول إلى معلمات القالب غير المتخصصة غير من النوع. ولكن هنا طريقة لعدم تكرار نفسك في تنفيذ 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>
{};
لهذا المثال، لا يكسب المرء أكثر من اللازم، حيث يحتاج المرء إلى كتابة 4,0
مرتين (- هل يمكنك كتابة ذلك وكذلك المرة الثانية في cout
في المرجع الخاص بك). ولكن يبدأ في الدفع إذا كان لديك المزيد من الوظائف باستخدام معلمات القالب.