[EMAIL PROTECTED] writes: > Some compilers really compile it.
It compiles fine. It just doesn't link. > VC71, BCB 2006 > It works. I have no clue what 'BCB 2006' is, but VC71 fails to link it just like most of the other compilers: $ cl junk.cpp # junk.cpp is the code you posted, *verbatim* Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86 Copyright (C) Microsoft Corporation 1984-2002. All rights reserved. junk.cpp Microsoft (R) Incremental Linker Version 7.10.3077 Copyright (C) Microsoft Corporation. All rights reserved. /out:junk.exe junk.obj junk.obj : error LNK2019: unresolved external symbol "void __cdecl doFunc<bool>(void)" ([EMAIL PROTECTED]@@YAXXZ) referenced in function "private: void __thiscall foo<bool>::notUsed(void)" ([EMAIL PROTECTED]@_N@@AAEXXZ) junk.exe : fatal error LNK1120: 1 unresolved externals > If g++ does not generate the code for "foo<bool>::notUsed()", how does > g++ know that "doFunc<bool>()" is needed. But g++ *is* generating the code (because you asked it to): $ /usr/local/gcc-3.4.6/bin/g++ -c junk.cpp $ nm junk.o U _Z6doFuncIbEvv 00000000 W _ZN3fooIbE7notUsedEv U __gxx_personality_v0 00000000 T main $ nm -C junk.o U __gxx_personality_v0 00000000 T main U void doFunc<bool>() 00000000 W foo<bool>::notUsed() <<< see! that's the generated code > NO, of course I don't want to instantiate foo<bool>::notUsed(). In that case, *why* are you asking compiler to instantiate it (with explicit template instantiation request)? > Instantiating "foo<bool>::notUsed()" would instantiate > "doFunc<bool>()". Unfortunatelly, "doFunc<...>()" does not work for > "bool". Therefore, using "notUsed()" for type "foo<bool>" should be > prohibited. The way to prohibit its instantiation is to provide a specialization that does not compile (compile-time assert) or that aborts at runtime. > For "VC71" and "BCB 2006" the way shown in the example works: > a) I do not use "foo<bool> obj; obj.notUsed();" > => links well Your code does *not* link with VC71. You are not telling the whole story. > b) I use "foo<bool> obj; obj.notUsed();" > => linker error (exactly what I want, because notUsed() is not > available for foo<bool>) > > With g++ case (a) does not link :( Case (a) will link just fine if you remove explicit instantiation request: $ cat junk.cpp template <typename T> void doFunc(); template <typename T> struct foo { void notUsed(); }; template <typename T> inline void foo<T>::notUsed() { doFunc<T>(); // <---- Linker cannot find doFunc<bool>() } // template class foo<bool>; // <<< BOGUS instantiation request int main() { #if USE_FOO_BOOL foo<bool> obj; obj.notUsed(); // should fail to link #endif return 0; } $ /usr/local/gcc-3.4.6/bin/g++ junk.cpp && echo ok ok # links just fine And case (b) will fail: $ /usr/local/gcc-3.4.6/bin/g++ junk.cpp -DUSE_FOO_BOOL /tmp/ccspuWsG.o: In function `foo<bool>::notUsed()': /tmp/ccspuWsG.o(.gnu.linkonce.t._ZN3fooIbE7notUsedEv+0x7): undefined reference to `void doFunc<bool>()' collect2: ld returned 1 exit status So it seems to me that g++ will already do exactly what you want IFF you remove the explicit instantiation request. Cheers, -- In order to understand recursion you must first understand recursion. Remove /-nsp/ for email. _______________________________________________ help-gplusplus mailing list help-gplusplus@gnu.org http://lists.gnu.org/mailman/listinfo/help-gplusplus