legal c++?

N

Noah Roberts

template < typename T1, typename T2, T2 T1::*x >
struct test1
{
};

struct test2
{
int x;

typedef test1<test2, int, &test2::x> type;
};

int main()
{
test2 t2;
test2::type t1;
}

Compiles with g++ and comeau online (warnings about unused variables)
but MS compiler gives error:

error C2327: 'test2::x' : is not a type name, static, or enumerator
e:\playground_projects\testing_ground\testing_ground\testing_ground.cpp 14
1 Error
error C2065: 'x' : undeclared identifier
e:\playground_projects\testing_ground\testing_ground\testing_ground.cpp 14
2 Error


I'm assuming MS is broken, since comeau accepts, but can anyone validate?
 
P

Pawel Dziepak

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Noah said:
template < typename T1, typename T2, T2 T1::*x >
struct test1
{
};

struct test2
{
int x;

typedef test1<test2, int, &test2::x> type;
};
Compiles with g++ and comeau online (warnings about unused variables)
but MS compiler gives error:
<snip>

14.3.2/1:
"[Template argument should be one of:] (...) the address of an object or
function with external linkage, including function templates and
function template-ids but *excluding non-static class members*"

Compiler wouldn't know the address of test2::x at compile time, that's
why such things are not allowed.

Pawel Dziepak
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkkR8C4ACgkQPFW+cUiIHNrDIACfYVvwReF/1KKqX+0EowfuWAqD
k/QAnRfZOiukU36PbYKwJd7St0vNhnj9
=0PVr
-----END PGP SIGNATURE-----
 
A

aschepler

Noah said:
template < typename T1, typename T2, T2 T1::*x >
struct test1
{
};
struct test2
{
  int x;
  typedef test1<test2, int, &test2::x> type;
};

Compiles with g++ and comeau online (warnings about unused variables)
but MS compiler gives error:

<snip>

14.3.2/1:
"[Template argument should be one of:] (...) the address of an object or
function with external linkage, including function templates and
function template-ids but *excluding non-static class members*"

Compiler wouldn't know the address of test2::x at compile time, that's
why such things are not allowed.

&test2::x does not have an address, it is a pointer to member value.
The very next portion of 14.3.2/1 specifically allows "a pointer to
member as described in 5.3.1" as a non-type template parameter.

I suspect this is indeed a compiler bug, but the details of when a
class member declaration may be referenced get tricky. To separate
the templating from the issue, I wonder if this would be a workaround,
or if not, I'd be curious on which line your compiler gives an error:

struct test2
{
int x;
static int test2::*const ptr_to_x = &test2::x;
typedef test1<test2, int, ptr_to_x> type;
};
 
N

Noah Roberts

I suspect this is indeed a compiler bug, but the details of when a
class member declaration may be referenced get tricky. To separate
the templating from the issue, I wonder if this would be a workaround,
or if not, I'd be curious on which line your compiler gives an error:

struct test2
{
int x;

this one:
static int test2::*const ptr_to_x = &test2::x;

errors:
test2::x is not a type name, static, or enumerator <- bad error I think.
x: undeclared identifier <- definitely a bad error (scope is guaranteed
here by standard)
test2::ptr: only static const integral data members can be initialized
within a class <- I think this error is legit.

and this one:
typedef test1<test2, int, ptr_to_x> type;

errors:
x: invalid template argument for 'test1', expected compile-time constant
expression. <- legit error I believe.
 
A

Andrey Tarasevich

the templating from the issue, I wonder if this would be a workaround,
or if not, I'd be curious on which line your compiler gives an error:

struct test2
{
int x;
static int test2::*const ptr_to_x = &test2::x;
typedef test1<test2, int, ptr_to_x> type;
};

It would be rather strange to expect this to work as a workaround, since
static members of non-integral/non-enum type cannot have in-class
initializers in C++.
 
A

Andrey Tarasevich

Noah said:
I'm assuming MS is broken, since comeau accepts, but can anyone validate?

I'd say that MS compiler is definitely broken in this regard. Members of
an incomplete class can be looked up in from the declaration of another
member of the same class, as long as the latter follows the former
(3.3/5). MS compiler also knows about that, since it will look up enum
members following this rule. It just appears that the authors simply
didn't realize that there's a perfectly legal context where an ordinary
data member name might be looked up.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top