Bug 26205 - pointer to member template parameter can't be null
Summary: pointer to member template parameter can't be null
Status: RESOLVED DUPLICATE of bug 10541
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.4
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-02-10 01:08 UTC by Jeff Petersen
Modified: 2013-11-15 18:05 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-02-15 19:37:18


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeff Petersen 2006-02-10 01:08:50 UTC
struct Simple
{
    int a;
};

template <typename T, int T::*U> struct Test
{
    void Foo(T *obj, int v)
    {
        if (U != 0)
            obj->*U = v;
    }
};

int main(int argc, const char **argv)
{
    Test<Simple, &Simple::a> t1;    // ok
    Test<Simple, 0> t2;             // error, but should not be (works in MSVC 7/8)

    Simple s;
    t1.Foo(&s, 5);
}


Note: it also won't let you specify a default parameter of 0 for the template parameter:

template <typename T, int T::*U = 0> struct Test   // won't do this either

MSVC 7/8 handle the first case, but also can't handle the default parameter (they crash with an internal compiler error).  MSVC 7/8 also won't handle specialization of the Foo function for the 0 case, though the resultant code generated is the same since the branch is optimized out.  I only mention this to give you some other nuances to check for once the base bug is fixed.
Comment 1 Andrew Pinski 2006-02-10 01:19:35 UTC
Comeau gives the following error:


"ComeauTest.c", line 19: error: argument of type "int" is incompatible with
          template parameter of type "int Simple::*"
      Test<Simple, NULL> t2;             // error, but should not be (works in
                   ^
Comment 2 Wolfgang Bangerth 2006-02-15 19:37:18 UTC
icc gives essentially the same error as that one mentioned by Andrew for
Comeau (not surprisingly). As a workaround, you can always use an explicit
cast:
    Test<Simple, (int Simple::*)0> t2;


I believe the code is ok anyway, see 4.11/1.

W.
Comment 3 Jeff Petersen 2006-02-15 19:55:54 UTC
The casting work-around doesn't compile under GCC.  It requires that the template parameter be a constant-expression (which is true), which results in the following error:

error: a casts to a type other than an integral or enumeration type cannot appear in a constant-expression

I have yet to be able to figure out a work-around.  MSVC allows the cast, but works with or without it.
Comment 4 Paolo Carlini 2013-11-15 18:05:41 UTC
Nothing to fix here, besides maybe the casting bit in c++98 mode which is PR10541.

*** This bug has been marked as a duplicate of bug 10541 ***