On 15 November 2011 05:56, vagran.ast wrote: > On 11/14/2011 11:28 PM, Jonathan Wakely wrote: >> >> On 14 November 2011 20:22, vagran.ast wrote: >>> >>> Hi, >>> >>> In the following code: >>> >>> class A { >>> public: >>> void SomeMethod() { } >>> }; >>> >>> template<class T, void (T::*SomeMethod)() = 0> >>> class B { >>> >>> }; >>> >>> B<A> b1; // error: could not convert template argument '0' to 'void >>> (A::*)()' >>> >>> B<A, 0> b2; // error: could not convert template argument '0' to 'void >>> (A::*)()' >>> >>> void (A::*someMethod)() = 0; // OK >>> >>> there are two compilation errors. AFAIK per C++ standard 0 is a valid >>> value >>> for a pointer to member >>> function. Variable of such type can be successfully initialized by 0 but >>> template arguments can not. >>> Is it desired behavior or a bug? >> >> I think G++ is correct, you need to cast the literal zero to the right >> type to prevent it being treated as an int in that context, or use >> C++11's nullptr. > > I have tried both variants and still no luck: > > B<A, static_cast<void (A::*)()>(0)> b2; > // error: '((void (A::*)())0)' is not a valid template argument for type > 'void (A::*)()' > // error: it must be a pointer-to-member of the form '&X::Y' > // error: could not convert template argument '((void (A::*)())0)' to 'void > (A::*)()' > // error: invalid type in declaration before ';' token > > B<A, nullptr> b3; // error: could not convert template argument 'nullptr' to > 'void (A::*)()' > > void (A::*someMethod)() = static_cast<void (A::*)()>(0);// OK > void (A::*someMethod2)() = nullptr;// OK > > Seems the compiler wants only real method pointer for a template parameter > however > the conversion from NULL to member function pointer is possible. That's a bug, maybe related to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35167 Using nullptr works with GCC 4.7 I think this should work too: typedef void (A::*pmf_type)(); const pmf_type pmf_constant = 0; template <class T, void (T::*SomeMethod)() = pmf_constant> class B { };