Sziasztok!
Azt szeretném elérni, hogy több osztály ugyanazon nevű statikus adattagjának fordítás időben adjunk egymástól diszjunkt értékeket. Tehát :
#include <iostream>
class A {
public : static const int MSGID = ?
};
class B {
public : static const int MSGID = ?
};
class C {
public : static const int MSGID = ?
};
int main()
{
std::cout << A::MSGID << std::endl;
std::cout << B::MSGID << std::endl;
std::cout << C::MSGID << std::endl;
return 0;
}
Mit javasolnátok a ? helyére, ha a kimenetben pl
1
2
3
-t szeretnék látni?
Vagy másképpen fogalmazva milyen metaprogram ekvivalens a következővel:
int next()
{
static int cnt = 1;
return cnt++;
};
class A { public : static int MSGID; };
int A::MSGID = next();
...
Nyilván valamiféle
MSGID = generator< T >::next;
-ben kell gondolkodni, legalább 1 template paraméter kell.
Természetesen szám paraméterrel meg lehet oldani, de annak nincs értelme, hisz akkor már bele is égethetnénk a kódba az értékeket.
Csak ötleteket várok!
- 2121 megtekintés
Hozzászólások
curiously recurring template pattern?
http://www.google.hu/search?hl=hu&q=curiously+recurring+template&btnG=G…
- A hozzászóláshoz be kell jelentkezni
Csak én nem látom ez miért segít?
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
nem, en is latom :)
nem figyeltem, hogy static const-nak kellene lennie az azonositonak
ez csak akkor lenne jo, ha nem forditasi idoben kene erteket adni...
- A hozzászóláshoz be kell jelentkezni
Nem a fordítási idő a lényeges, amit linkeltél az szimplán mást csinál.
Az azonos osztályba tartozó objektumok létrehozásait számolja.
verkri viszont az osztályokhoz szeretne egy azonosító számot.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
az egy pattern... nem csak arra lehet hasznalni...
raadasul ha egy osztalyvaltozod, ami nem konstans, es azzal szamolod az objektumokat,
a leszarmazattban (ami ugye ebbol a template-bol szarmazik es sajat magat adja at sablonparameterkent) beteszel egy peldanyvaltozot, aminek ertekul adod az osztalyvaltozo akt. erteket(tkeppen lemented a szamlalo allapotat a peldany szamara letrehozaskor), akkor az is lehet azonosito...
de ez futasi ido, nem forditasi
- A hozzászóláshoz be kell jelentkezni
Nyilván nem csak arra... Sőt elsősorban nem arra szokták.
Ettől még köze sincs a jelenlegi problémához...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Nálam a következő program azt valósítja meg, amit szerettél volna:
#include iostream // kacsacsőrök eltávolítva. a kijelezhetőség végett
class A {
public : static const int MSGID = 1;
};
class B {
public : static const int MSGID = 2;
};
class C {
public : static const int MSGID = 3;
};
int main()
{
std::cout << A::MSGID << std::endl;
std::cout << B::MSGID << std::endl;
std::cout << C::MSGID << std::endl;
return 0;
}
g++ -val fordítottam.
- A hozzászóláshoz be kell jelentkezni
neeee... ilyeneket ne.
"Természetesen szám paraméterrel meg lehet oldani, de annak nincs értelme, hisz akkor már bele is égethetnénk a kódba az értékeket."
Érted ?
- A hozzászóláshoz be kell jelentkezni
kacsacsőrök eltávolítva. a kijelezhetőség végett
less than és greater than segíthet.
--
unix -- több, mint kód. filozófia.
Life is feudal
- A hozzászóláshoz be kell jelentkezni
Konkretan a < es > HTML tagek. Amugy telleg jo lenne, ha trey csinalna valamit, a regi HUP-on ez ment. En fel tudnam aldozni a kodon beluli html formazas lehetoseget, ha ezzel visszaallna a regi mukodes.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Eleve nem értem minek vannak engedélyezett HTML tag-ek.
Max arra jók, hogy szétcsapják az oldalt, ha a kedves user nem zárta le őket...
Közben meg vannak a BBCode-ok is, ahol ez a probléma nem áll fent.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Azért mert nagyon durván bugos a Drupal [url] kezelése.
Tulajdonképpen Wikipédia linkeket nem fogad el (illetve nagyon kis százalékban).
- A hozzászóláshoz be kell jelentkezni
Nekem eddig még csak a zárójeleket nem szerette...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Talán emiatt: http://www.codinghorror.com/blog/archives/001181.html
- A hozzászóláshoz be kell jelentkezni
Ha nem a deklarációban adod meg az MSGID-et, akkor megadhatod értéknek egy fv kimenetét:
const int C::MSGID = Counter::inc();
Ha ez a statikus fv lökdös egy statikus számlálót, mindig más értéket kapsz.
Azt mondjuk érdemes megjegyezni, hogy a statikus adattagok kezdeti értékadásának sorrendjét semmi sem garantálja, attól függően, hogy milyen sorrendben linkelsz más más eredményt kaphatsz...
(Az persze garantált, hogy inicializálva lesz mielőtt először hozzáférsz.)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
ez nem fordításidejű.
- A hozzászóláshoz be kell jelentkezni
Nem.
Viszont működik. :)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Először én is valami template-es megoldáson törtem a fejem, de félek az nem lehetséges...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
template-nek template:
#include <iostream>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/find.hpp>
class A;
class B;
class C;
typedef boost::mpl::vector<A,B,C> classes;
class A {
public:
static const int MSGID = boost::mpl::find<classes,A>::type::pos::value;
};
class B {
public:
static const int MSGID = boost::mpl::find<classes,B>::type::pos::value;
};
class C {
public:
static const int MSGID = boost::mpl::find<classes,C>::type::pos::value;
};
int main()
{
std::cout << A::MSGID << std::endl;
std::cout << B::MSGID << std::endl;
std::cout << C::MSGID << std::endl;
return 0;
}
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
A template metaprogramozás Turing-teljes, így _MINDEN_ ami kiszámítható, megvalósítható. Csak kérdés, hogy hogyan.:D
- A hozzászóláshoz be kell jelentkezni
Funkcionális nyelvekben alkalmazható technikákat használva. A generátor sajnos nem ilyen, és kb. csak úgy lehet ahogy tr3w írta.
- A hozzászóláshoz be kell jelentkezni
A generator< T >-re gondolsz, amit írtam ? Azt csak példának írtam, természetesen ettől el lehet térni. És mit értesz metaprogramozásban funcionális technikák alatt ?
- A hozzászóláshoz be kell jelentkezni
Arra gondolok, hogy a kifejezésekből egy végrehajtási gráf épül, amiben egy-egy kifejezésnek mindig konstans az értéke. Tehát, ha két helyen szerepel ugyanaz a kifejezés, akkor ez a kettő ugyanazt jelenti, így generátor nem használható, vagyis minden msgid definíció valamiben el kell hogy térjen.
A legegyszerűbb ilyenkor, ha az őt tartalmazó típus az, amiben eltér a definíció, amihez érdemes makrót írni, aminek a paramétere az osztály neve. Szükség van még egy osztályok -> int leképezésre, amihez vagy specializációkat kell írni explicit hozzárendeléssel, vagy ha nem akarsz számokat írni, akkor egy listában felsorolhatod, ld. tr3w módszerét.
- A hozzászóláshoz be kell jelentkezni
Ha jól emlékszem ezt hívtuk úgy, hogy funkcionális nyelvekben nincs destruktív értékadás...
Kivéve, ha hülyeségeket beszélek...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Ezek egy fájlban vannak, ugye?
__LINE__ Integer value representing the current line in the source code file being compiled.
KisKresz
- A hozzászóláshoz be kell jelentkezni
Ez szellemes:)
- A hozzászóláshoz be kell jelentkezni
Hihi, nem rossz, nem rossz. Egy pontot megér. Viszont van egy rossz hírem : több fájlban is lehetnek ( legalábbis jó lenne támogatni ezt is ).
- A hozzászóláshoz be kell jelentkezni
Az a baj, hogy különböző fájlok fordítása egymástól független, így nem látom, hogy ezt meg lehetne oldani fordítási időben.
KisKresz
- A hozzászóláshoz be kell jelentkezni
Egy alkalmazáshoz tartozó, külön fájlok ( header-k ). Nem voltam egyértelmű, bocs.
- A hozzászóláshoz be kell jelentkezni
Egy barátom hívta fel rá a figylemem:
"VC++-on es talan GCC-n is van __COUNTER__
egyebkent http://lists.boost.org/Archives/boost/2002/10/38298.php"
Az első gondolom csak fordítási egységenként működik.
A második is, plusz még sérti a C++ szabványt is. De ennek ellenére sok fordítóval lefordul.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
subscribe
- A hozzászóláshoz be kell jelentkezni
// alma.cpp
#define NEXT2(x) __FILE__ ":" #x
#define NEXT1(x) NEXT2(x)
#define NEXT NEXT1(__LINE__)
struct A {
static const char id[];
};
struct B {
static const char id[];
};
struct C {
static const char id[];
};
const char A::id[] = NEXT;
const char B::id[] = NEXT;
const char C::id[] = NEXT;
- A hozzászóláshoz be kell jelentkezni
const int-ről volt szó...
Ha meg hash fv-t rendelsz hozzá akkor máris fordításidejű.
De akkor már itt egy hasonló:
class A {
public:
static const char* MSGID;
};
const char* A::MSGID = typeid(A).name();
class B {
public:
static const char* MSGID;
};
const char* B::MSGID = typeid(B).name();
class C {
public:
static const char* MSGID;
};
const char* C::MSGID = typeid(C).name();
int main()
{
std::cout << A::MSGID << std::endl;
std::cout << B::MSGID << std::endl;
std::cout << C::MSGID << std::endl;
return 0;
}
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
#include
class A;
class B;
class C;
template
struct What {
enum { RET = 1 };
};
template <>
struct What {
enum { RET = 1 };
};
template <>
struct What {
enum { RET = 2 };
};
template <>
struct What {
enum { RET = 3 };
};
class A {
public:
static const int MSGID = What::RET;
};
class B {
public:
static const int MSGID = What::RET;
};
class C {
public:
static const int MSGID = What::RET;
};
int main()
{
std::cout << A::MSGID << std::endl;
std::cout << B::MSGID << std::endl;
std::cout << C::MSGID << std::endl;
return 0;
}
- A hozzászóláshoz be kell jelentkezni
A kód fele nem látszik, de abból amit látni ez mindössze a kézzel megadott konstans bonyorultabb esete...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Legyszives 5-10 sorosnal nagyobb kodok eseteben pastebin, koszi.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Tényleg jobb pastebinnel, csak most olvastam újra a hozzászólást :)
- A hozzászóláshoz be kell jelentkezni
Eleg, ha egy c++ fileon belul egyedi ? Vagy globalisan egyedi kell ?
Ha globalisn egydi kell, akkor javasolhatom a "sajat elfordito" lepest, vagyis c++ forgatas elott attolni egy csoda scripten minden filet.
Ha filen beluli akkor a __LINE__ macro sem rossz.
szerk:
Tovabb gondolva 100000 sornal csak nem hosszabb a kodod/c++ file es 20000 nel tobb filod nem igen lessz , tehat minden fileban eleg ennek kulonbozo tobszoroset hozza adni.
Amit nem lehet megirni assemblyben, azt nem lehet megirni.
- A hozzászóláshoz be kell jelentkezni
+1 a forditas elotti sajat preprocesszor szkriptre.
De ha hajlando vagy minden fajl elejere beirni egy egyedi szamot akkor tedd azt:
#define FILE_ID 1
...
int id = __LINE__ * 10000 + FILE_ID;
- A hozzászóláshoz be kell jelentkezni
Ha globális kell, akkor arra is van megoldás:
static int a, b, c;
class A {
public:
static int ID;
};
class B { ... };
class C { ... };
A::ID = (int)&a;
B::ID = (int)&b;
C::ID = (int)&c;
Ez egyedi ID-t eredényez.
- A hozzászóláshoz be kell jelentkezni
Mondok jobbat, nem is kell az a, b, c valtozó.
A::ID = (int)&A::ID;
B::ID = (int)&B::ID;
C::ID = (int)&C::ID;
Legalábbis C-ben ez a kód fordult szépen:
static int a = (int)&a;
Gondolom c++-ban is megy.
- A hozzászóláshoz be kell jelentkezni
Szellemes, de ez is futasideju.
- A hozzászóláshoz be kell jelentkezni
A gond szerintem abban keresendo, hogy a c++ nem igazan tudja, hogy mik ezek a tagok, akkor sem, ha alaptipusok. A preprocesszor az ugye inkabb statikus cserekre van szakosodva (egy mini sed), a fordito meg mar nem nyulkalhat a preprocesszalt kodhoz ilyen valtoztatasokkal (o csak a garantalt operatorokat es konstruktor/destruktorokat generalhatja le). Innentol nem tudom, hova gondoltad beilleszteni az ertekadas folyamatat, foleg kulso, egyedileg eldontott valtozoertekadast. Mert ha azt mondom, hogy legyen a __LINE__ erteke, elkuldesz a rak farkara, mert konstans. __FILE__, _FUNCINFO__ - megint konstans.
Gondold at, hogy mi a feladat, mert szinte biztos, hogy nem jofele keresgelsz. Miert kell neked FORDITASI idoben ertekeket kapnod? Miert nem eleg a futasideju? Mondd el, mi a feladat, mert akkor talan segiteni is tudunk.
Szerk: ez a topicnyitonak akart menni... :S
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni