$ g++ find.mytree.cpp find.mytree.cpp:141:2: warning: no newline at end of file find.mytree.cpp:123: internal compiler error: in output_constant, at varasm.c:38 43 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions.
$ g++ -v Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs Configured with: /gcc/gcc-3.4.4/gcc-3.4.4-1/configure --verbose --prefix=/usr -- exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --man dir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77, java,objc --enable-nls --without-included-gettext --enable-version-specific-runt ime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --ena ble-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=b oehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchroniza tion --enable-libstdcxx-debug : (reconfigured) Thread model: posix gcc version 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125) find.mytree.cpp ======================== #include <iostream> #include <string> #include <map> #include <vector> #define OUTPUT(x) std::cout << x << std::endl; template <typename C> class mytree { public: typedef mytree<C> MYTREE; typedef std::map<const std::string, MYTREE*> ELEMENT; typedef typename ELEMENT::iterator ELEITER; #define GETTREE(x) (*(x->second)) #define VALUE(x) (make_pair(x->Name(), x)) typedef std::string NAME; mytree(char *nm, C& vl, MYTREE *ch=0, MYTREE *brss=0, MYTREE* pr=0) : name(nm), value(vl){ insert (ch, brss, pr); } mytree(const char* nm, const C& vl, MYTREE *ch=0, MYTREE *brss=0, MYTREE* pr=0) : name(nm), value(vl){ insert (ch, brss, pr); } MYTREE& operator/(const char* str) { return myfind(child, str); } MYTREE& operator|(const char* str) { return myfind(brosis, str); } MYTREE& operator^(const char* str) { return myfind(parents, str); } const C& Value() { return value; } const NAME &Name() { return name; } operator C () { return value; } /* noloop: to avoid infinite loop. consider A add B as brother and at mean time B add A as brother. then A add B as brother... that will be infinite loop. solution: (a) we can find each time to see if B is already A's brother (b) add the noloop, when it should be finished, just set noloop to 0. */ MYTREE& insert(MYTREE *ch, MYTREE *brss, MYTREE* pr, bool noloop=1) { counter++; if(ch){all.insert(VALUE(ch)); child.insert(VALUE(ch)); if(noloop)ch->insert(0, 0, this, 0);} if(brss){all.insert(VALUE(brss));brosis.insert(VALUE(brss)); if(noloop)brss->insert(0, this, 0, 0);} if(pr){all.insert(VALUE(pr));parents.insert(VALUE(pr)); if(noloop)pr->insert(this, 0, 0, 0);} return *this; } void dump(MYTREE *caller=0, std::string lv="") { typename ELEMENT::iterator it; MYTREE *tr = this; //dump all brosis it = this->brosis.begin(); while(it != this->brosis.end()) { tr = &GETTREE(it); assert(tr); if(tr != caller && tr != this) { tr->dump(this, lv); //OUTPUT(lv << "|" << tr->Name() << ": " << tr->Value() ); } ++it; } OUTPUT(lv<< " " << this->Name() << ": " << this->Value() ); //dump all child it = this->child.begin(); while(it != this->child.end()) { tr = &GETTREE(it); assert(tr); if(tr != caller && tr != this) { //OUTPUT(lv << "\t\\" << tr->Name() << ": " << tr->Value() ); tr->dump(tr, lv+"\t"); } ++it; } } static void dumpall() { ELEITER it = all.begin(); while(it!= all.end()) { OUTPUT(it->first <<" " << it->second ); ++it; } } /*static ELEMENT& getall() { return all;}*/ private: MYTREE& myfind(ELEMENT& el, const char* str) { typename ELEMENT::iterator it = el.find(NAME(str)); if ( it != el.end() ) return GETTREE(it); return *this; } NAME name; ELEMENT child; ELEMENT brosis; ELEMENT parents; static ELEMENT all; static int counter; C value; }; template<int> int mytree<int>::counter = 0; /* template<typename C> std::map<const std::string, mytree<C>* > mytree<C>::all = std::map<const std::string, mytree<C>* >();// This line OK!! */ // This line will failed! template<int > std::map<const std::string, mytree<int>* > mytree<int>::all = std::map<const std::string, mytree<int>* >(); int main() { mytree<int> my1("temp01", 1); mytree<int> my2("root", 2, new mytree<int>("hello", 3, new mytree<int>("world", 4))); my2.insert(0, new mytree<int>("my3", 5), new mytree<int>("my4", 6)); std::cout << my2/"hello"/"world" << std::endl; std::cout << (my2/"hello"/"world"^"hello") <<std::endl; std::cout << (my2|"my3"|"root") << std::endl; std::cout <<(my2^"my4")/"root" << std::endl; (my2/"hello").insert(0, new mytree<int>("my5", 10),0); OUTPUT((my2/"hello"^"root")/"hello"); mytree<int>::dumpall(); my2.dump(/*&my2*/); return 0; } -- Summary: Template Specialization break down Product: gcc Version: 3.4.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: ypwangandy at gmail dot com GCC build triplet: i686-pc-cygwin GCC host triplet: i686-pc-cygwin GCC target triplet: i686-pc-cygwin http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29766