Why is address of non-static member not allowed as template non-type parameter?
First, to use pointers/references to subobjects, you'd need to be able to mangle them. That's a pretty big undertaking.
Second, and probably more importantly, from N4198:
The restriction that the constant expression must name a complete object is retained to avoid aliasing problems with pointers to subobjects:
struct A { int x, y; } a; template<int*> struct Z; using B = Z<&a.x + 1>; using C = Z<&a.y>; // Are B and C the same type?
To quote Richard Smith,
The answer "yes" is problematic because there are things you can do with a pointer to [
a.y
] that would have undefined behavior if performed on a pointer past the end of [a.x
] The answer "no" is problematic because they (in typical implementations) represent the same address.
Replace your main with this piece of code
int main(void)
{
constexpr static int bb = 5;
constexpr test<&bb> t;
return 0;
}
and you will receive the error bb cannot be used as a template argument because it has no linkage ( not to be mistaken with linker related staff ) .
Class data members cannot be accessed unless they are referenced through the object, and cannot be taken into account during template instantiation, since data members do not have linkage, i.e. they are not defined symbols and therefore cannot be used as template arguments.
That being said , doing a readelf you can verify this:
48: 00000000004006ac 4 OBJECT LOCAL DEFAULT 14 q0
68: 000000000060097c 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
69: 0000000000600978 4 OBJECT GLOBAL DEFAULT 23 q::a
but there is no q0.b
defined . The alternative would be to name (mangle) none static class members which would strip dynamic capabilities of the language.