* Template argument (pointer to member function) initialization with NULL @ 2011-11-14 21:48 vagran.ast 2011-11-14 21:51 ` Jonathan Wakely 0 siblings, 1 reply; 5+ messages in thread From: vagran.ast @ 2011-11-14 21:48 UTC (permalink / raw) To: gcc-help 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? gcc version 4.6.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Template argument (pointer to member function) initialization with NULL 2011-11-14 21:48 Template argument (pointer to member function) initialization with NULL vagran.ast @ 2011-11-14 21:51 ` Jonathan Wakely 2011-11-15 13:15 ` vagran.ast 0 siblings, 1 reply; 5+ messages in thread From: Jonathan Wakely @ 2011-11-14 21:51 UTC (permalink / raw) To: vagran.ast; +Cc: gcc-help 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. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Template argument (pointer to member function) initialization with NULL 2011-11-14 21:51 ` Jonathan Wakely @ 2011-11-15 13:15 ` vagran.ast 2011-11-15 19:55 ` Jonathan Wakely 0 siblings, 1 reply; 5+ messages in thread From: vagran.ast @ 2011-11-15 13:15 UTC (permalink / raw) To: Jonathan Wakely; +Cc: gcc-help 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. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Template argument (pointer to member function) initialization with NULL 2011-11-15 13:15 ` vagran.ast @ 2011-11-15 19:55 ` Jonathan Wakely 2011-11-16 21:11 ` vagran.ast 0 siblings, 1 reply; 5+ messages in thread From: Jonathan Wakely @ 2011-11-15 19:55 UTC (permalink / raw) To: vagran.ast; +Cc: gcc-help 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 { }; ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Template argument (pointer to member function) initialization with NULL 2011-11-15 19:55 ` Jonathan Wakely @ 2011-11-16 21:11 ` vagran.ast 0 siblings, 0 replies; 5+ messages in thread From: vagran.ast @ 2011-11-16 21:11 UTC (permalink / raw) To: Jonathan Wakely; +Cc: gcc-help On 11/15/2011 11:30 AM, Jonathan Wakely wrote: > 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 { }; I have checked the workaround: typedef void (A::*pmf_type)(); const pmf_type pmf_constant = 0; template<class T, void (T::*SomeMethod)() = pmf_constant> class B { }; It doesn't work on 4.6 with the same error. And with the latest snapshot of GCC 4.7: class A { public: void SomeMethod() { } }; template<class T, void(T::*SomeMethod)() = nullptr> class B { }; B<A> b1; //OK B<A, static_cast<SomeMethod_t>(0)> b2; //OK B<A, nullptr> b3; //OK B<A, 0> b4; // error: could not convert template argument ‘0’ to ‘void (A::*)()’ So everything works as expected in 4.7. Thanks! ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-11-16 18:29 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-11-14 21:48 Template argument (pointer to member function) initialization with NULL vagran.ast 2011-11-14 21:51 ` Jonathan Wakely 2011-11-15 13:15 ` vagran.ast 2011-11-15 19:55 ` Jonathan Wakely 2011-11-16 21:11 ` vagran.ast
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).