[ Časlav Ilić @ 13.03.2006. 10:58 ] @
Mogu li nekako da zabranim instanciranje šablona (dobijem grešku pri kompilaciji) za neki određeni tip, za koji bi se šablon inače mogao instancirati?

Na primer, ako je šablon:

Code:
template <typename A>
int myWheel (const A &a) {
    return sizeof(a);
}


želim da se ne može instancirati za char:

Code:
int i;
myWheel(i); // može
char c;
myWheel(c); // ne može
[ NrmMyth @ 13.03.2006. 11:23 ] @
pogledaj predprocesorske direktive... mozda nadjes nesto tamo.
Sad samu u zurbi pa ne mogu to napraviti za tebe.
[ NastyBoy @ 13.03.2006. 13:21 ] @
Koristi specijalizaciju templejta. Recimo:
Code:

template <>
int myWheel (const char &a) 
{
#error "No can do!!!!";
};


Ovo daje compile-time error, naravno.


[Ovu poruku je menjao NastyBoy dana 13.03.2006. u 14:23 GMT+1]
[ Časlav Ilić @ 13.03.2006. 13:41 ] @
Eh, nije da nije i meni sevnulo, ali to nažalost daje grešku još pre kompilacije...
[ NastyBoy @ 13.03.2006. 13:54 ] @
Sorry, my bad. Napisao sam u zhurbi, zaboravio da se to evaluira bez obzira na instanciranje.

Elem, zameni ono #error sa jednim
Code:

assert(0 && "Ne mozhe se instancirati char templejt!");
return -1;

i to je to. Mada ovako dobijash run-time umesto compile-time greshke.

[Ovu poruku je menjao NastyBoy dana 13.03.2006. u 14:55 GMT+1]
[ NastyBoy @ 13.03.2006. 14:04 ] @
Da dodam - za compile time error deklarishi specijalizovani templejt, ali NEMOJ da ga implementirash. Ako neko koristi char-specijalizaciju dobice linker-error.
[ Časlav Ilić @ 13.03.2006. 14:29 ] @
Nije vala loše ni da pukne pri povezivanju, tek da samo da se program ne izgradi do kraja. Nisam o tome razmišljao, zahvaljujem.

(Mada, ako se neko doseti kako da pukne pri kompilaciji, neka ga ne mrzi da objasni :)
[ Dragi Tata @ 13.03.2006. 16:17 ] @
Nisu mi knjige pri ruci, ali proguglaj malo "compile time asserts"
[ leka @ 13.03.2006. 16:45 ] @
Code:

/*********************************************************\
file:        notinst.cpp
compile:     g++ notinst.cpp -o notinst
run:         ./notinst
author(s):   Dejan Lekic, http://dejan.lekic.org
\*********************************************************/

#include <cassert>
#include <iostream>

template <typename A>
int myWheel (const A &a) 
{
    // If You do not want to break the application change assert() to if() .
    assert(typeid(a) != typeid(char));
    return sizeof(a);
}

struct TmpStruct
{
    int one;
    double two;
    std::string three;
};

int main(int argc, char** argv)
{
    char tmp1 = 'd';
    int tmp2 = 5;
    TmpStruct oTmp;
    std::cout << myWheel(tmp2) << std::endl; // OK
    std::cout << myWheel(tmp1) << std::endl; // !OK
    std::cout << myWheel(oTmp) << std::endl; // OK
    return 0;
}


[Ovu poruku je menjao leka dana 13.03.2006. u 17:47 GMT+1]
[ NastyBoy @ 13.03.2006. 18:15 ] @
Citat:
Nisu mi knjige pri ruci, ali proguglaj malo "compile time asserts"


Da, Alexandrescu ima celo poglavlje na temu "compile-time assert", ali nemam ni ja knjige pri ruci niti se trenutno secam kako to tachno ide :)

Prepisacu to reshenje ovde kasnije vecheras
[ Časlav Ilić @ 13.03.2006. 18:19 ] @
(Leko: treba da pukne pri kompilaciji, ne u radu)

Po Nemanjinom uputu (svaka mu se dala), proguglah za tim statičkim potvrdama, i sastavih nešto ovako:

Code:
template <typename T> class TypeValid { public: static const int ok = 1; };
template <> class TypeValid<char> { public: static const int ok = 0; };
#define STATIC_ASSERT_NOT_CHAR(T) switch(0) {case 0: case TypeValid<T>::ok:;}

template <typename A>
int myWheel (const A &a) {
    STATIC_ASSERT_NOT_CHAR(A);
    return sizeof(a);
}

int main () {
    int i;
    myWheel(i); // compiles
    char c;
    myWheel(c); // error, duplicate case
}


Pitam se sad:

1) može li elegantnije, i

2) umesto da kompilator samo kaže kako je dupliran slučaj, mogu li nekako da proturim svoju poruku, makar i uvijeno (npr. ime nedeklarisane promenljive)?
[ NastyBoy @ 13.03.2006. 18:31 ] @
Citat:
2) umesto da kompilator samo kaže kako je dupliran slučaj, mogu li nekako da proturim svoju poruku, makar i uvijeno (npr. ime nedeklarisane promenljive)?


Mozhe, bash to je u Alexandrescu-ovoj knjizi. Mozhda je okachio to poglavlje na svom sajtu. Ako ne, postovacu ja to ovde kasnije.
[ Dragi Tata @ 13.03.2006. 18:43 ] @
Da, evo ga ovde: http://www.openoffice.org/serv...?msgId=930121&listName=dev
[ leka @ 13.03.2006. 19:18 ] @
Da, izvinjavam se jer nisam obratio paznju da treba prekinuti kompajliranje... Da bi se izvelo to sto hoces covek mora da napravi neku zestoku budzavinu...

Da malo odletim sa teme - programski jezik D ima "static assert" kao deo jezika, bilo bi lepo da C++ ima nesto slicno...
[ Časlav Ilić @ 13.03.2006. 20:04 ] @
Po još jednom Tatinom hirurškom uputu, evo i kraće i s „porukom“:

Code:
#define ERR_MSG Dont_you_know_that_char_is_not_a_wheel
template <typename T> class TypeValid {public: static void ERR_MSG () {}};
template <> class TypeValid<char> {};
#define STATIC_ASSERT_NOT_CHAR(T) TypeValid<T>::ERR_MSG ();

template <typename A>
int myWheel (const A &a) {
    STATIC_ASSERT_NOT_CHAR(A);
    return sizeof(a);
}

int main () {
    int i;
    myWheel(i); // compiles
    char c;
    myWheel(c); // error, ERR_MSG not a member function
}


Citat:
leka:
Da bi se izvelo to sto hoces covek mora da napravi neku zestoku budzavinu...

Počinje da mi se čini da Đavoljev najveći uspeh nije što je ubedio ljude da ne postoji, već što je naterao izvesnog Danca da...
[ NrmMyth @ 13.03.2006. 21:46 ] @
Trudim se shvatiti, ali je previse
Citat:
#define ERR_MSG Dont_you_know_that_char_is_not_a_wheel
template <typename T> class TypeValid {public: static void ERR_MSG () {}};

Jeli moguce napisati funkciju koja ima isto ime kao i predprocesorski string.

Onda kasnije pukne jer nije nesto tu kako treba...

Nemam knjige kraj sebe pa ne mogu puno mozgati. Ako mozete pojasniti ovo.
Hvala.
[ Goran Arandjelovic @ 13.03.2006. 23:26 ] @
Moguće je napisati isto ime funkcije i predkompajlerskog stringa... upravo zato što to prvo prolazi predprocesor, pa tek onda ide na kompajliranje.

[Ovu poruku je menjao Goran Arandjelovic dana 14.03.2006. u 00:27 GMT+1]
[ NrmMyth @ 14.03.2006. 22:22 ] @
Tocno, krivo sam vidio gore, ucinilo mi se da je string, a nije.

Jasno mi je sad. MALO konfuzno na prvo oko.