This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Template argument (pointer to member function) initialization with NULL


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 { };


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]