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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux