maxsus shablon sinfi uchun statik a'zoni ishga tushirish

class A
{
};

template <typename A, int S>
class B
{
public:
        static int a[S];

        B()
        {
                a[0] = 0;
        }
};

template<> int B<A, 1>::a[1];

int main()
{
        B<A, 1> t;
        t;
}

U GCC 4.1 bo'yicha tuziladi, lekin bog'lamaydi:

static.cpp:(.text._ZN1BI1ALi1EEC1Ev[B<A, 1>::B()]+0x5): undefined reference to `B<A, 1>::a'

Iloji bo'lsa, ishga tushirishni ixtisoslashgan holda saqlashni afzal ko'raman, chunki massivda turga xos ma'lumotlar mavjud.


person kaspy    schedule 26.02.2010    source manba
comment
B‹A, 1›::a faqat 1 ta elementga ega emasmi? Shunday qilib, B‹A, 1›::a[1] ga murojaat qilib, siz massiv chegarasidan tashqarida indekslanmaysizmi?   -  person Dathan    schedule 26.02.2010
comment

Agar ma'lumotlar mijoz tomonidan yuborilishi kerak bo'lsa, uni serverga POST qiling. U serverda bo'lgandan so'ng, StringBuilder yarating va har bir satrdan keyin ustunlarni ajratuvchi va yangi qatorlar uchun vergul yordamida ma'lumotlarni katta satrga aylantiring. Keyin yangi FileResult-ni qaytaring:

StringBuilder sb ni yaratganingizdan so'ng kontrolleringizda:

MemoryStream ms = new MemoryStream();
StreamWriter writer = new StreamWriter(ms, Encoding.UTF8);
writer.Write(sb.ToString());
writer.Flush();
ms.Position = 0;

return File(ms, "application/vnd.ms-excel", "myfile.csv");

Excel ma'lumotlarini import qilish - bu boshqa voqea. Men buni ko'p qilmaganman, shuning uchun umid qilamanki, kimdir bu haqda ba'zi fikrlarni bera oladi.

  -  person Mike DeSimone    schedule 26.02.2010


Javoblar (3)


Statik a'zo ixtisoslashuvlari uchun, agar siz a'zoni ishga tushirmasangiz, u ixtisoslashuv deklaratsiyasi sifatida qabul qilinadi, u shunchaki "Oh, a'zoni asosiy shablondan yaratmang, chunki u erda boshqa joyda maxsus ta'rif". Shuni ta'kidlash kerakki, ta'rif .cpp faylida paydo bo'lishi kerak (aks holda siz teskarisini olasiz: bir nechta ta'riflar) va boshlang'ichsiz deklaratsiya hali ham sarlavha faylida joylashtirilishi kerak.

Endi to'g'ri sintaksis haqiqatan ham quyidagicha va u sarlavha faylida emas, lekin .cpp faylida ko'rsatilishi kerak.

template<> int B<A, 1>::a[1] = { };

Sarlavha faylida quyidagilar ko'rinishi kerak:

template<> int B<A, 1>::a[1];

Bu ixtisoslik deklaratsiyasi bo'lib xizmat qiladi.


Bundan kelib chiqadiki, siz faqat standart konstruktorga ega bo'lgan va nusxa ko'chirilmaydigan a'zoni ixtisoslashtira olmaysiz, chunki sizga ushbu sintaksis kerak bo'ladi:

// needs a copy constructor!
template<> Type Class<Arguments>::member = Type();

C++ 0x buni tuzatadi:

// doesn't anymore need a copy constructor
template<> Type Class<Arguments>::member{};

Bizning oramizdagi standart odamlar uchun iqtiboslar:

14.7.3/6:

Agar shablon, a'zo shabloni yoki sinf shablonining a'zosi aniq ixtisoslashgan bo'lsa, u holda bunday foydalanish sodir bo'lgan har bir tarjima birligida bu ixtisoslashuv bevosita instantsiyani yuzaga keltirishi mumkin bo'lgan birinchi foydalanishdan oldin e'lon qilinadi. ; diagnostika talab qilinmaydi.

14.7.3/15:

Shablonning statik ma'lumotlar a'zosining aniq ixtisoslashuvi, agar deklaratsiya ishga tushiruvchini o'z ichiga olgan bo'lsa, ta'rifdir; aks holda bu deklaratsiyadir. [Eslatma: standart ishga tushirishni talab qiladigan shablonning statik maʼlumotlar aʼzosini aniqlash uchun sintaksis yoʻq.

template<> X Q<int>::x;

Bu X sukut bo'yicha ishga tushirilishi mumkinligidan qat'iy nazar deklaratsiyadir (8.5). ]

3.2/3:

Har bir dastur ushbu dasturda ishlatiladigan har bir inline bo'lmagan funksiya yoki ob'ektning aniq bitta ta'rifini o'z ichiga olishi kerak; diagnostika talab qilinmaydi.

3.2/5:

Sinf turining bir nechta ta'riflari bo'lishi mumkin (9-band), ro'yxatga olish turi (7.2), tashqi aloqaga ega bo'lgan inline funksiya (7.1.2), sinf shabloni (14-band), statik bo'lmagan funksiya shablonlari (14.5.5) , dasturda ba'zi shablon parametrlari ko'rsatilmagan (14.7, 14.5.4) sinf shablonining statik ma'lumotlar elementi (14.5.1.3), sinf shablonining a'zo funksiyasi (14.5.1.1) yoki shablonning ixtisoslashuvi [.. .]

Buni "ba'zi shablon parametrlari ko'rsatilmagan" bilan cheklash bizuni sarlavhaga joylashtirib, quyidagi amallarni bajarishga ruxsat berilganligini bildiradi (shuning uchun bu ixtisoslikning bir nechta ta'riflari bo'lishi mumkin):

template<> template<typename T>
Type OuterClass<int>::InnerClass<T>::StaticMember = 0;

Sizning holatingizda, sizda barcha parametrlar ko'rsatilgan, bu bir nechta ta'riflarga ruxsat berish uchun bitta ta'rif qoidasi bilan qamrab olinmaydi.

person Johannes Schaub - litb    schedule 26.02.2010

Siz haqiqatan ham unga qiymat belgilashingiz kerak.

template<> int B<A, 1>::a[1] = {0};
person kennytm    schedule 26.02.2010
comment
Bu shablon‹› int B‹A, 1›::a = {0} bo'lishi kerak emasmi? - person Dathan; 26.02.2010
comment
@Dathan: Nima uchun? Sizning kodingiz error: conflicting declaration ‘int B<A, 1>::a’. - person kennytm; 26.02.2010
comment
@Dathan, bu deklaratsiya massivni emas, balki butun sonli a'zoni ixtisoslashtiradi. - person Johannes Schaub - litb; 26.02.2010

U bog'lanmaydi, chunki siz statik a'zongizga qiymat belgilamaysiz.

template<> int B<A, 1>::a[] = { 0 };

Tahrirlash:

Btw: Men har doim mahalliy C-turlari o'rniga boost::array dan foydalanishni afzal ko'raman:

class A { };

template <typename A, std::size_t S>
class B
{
public:
    static boost::array<int, S> a;

    B() { a[0] = 0; }
};

template<>  boost::array<int, 1> B<A, 1>::a = { };

int main()
{
    B<A, 1> t;
    cout << t.a[0] << endl;
}
person neverlord    schedule 26.02.2010