I'm experiencing a compile error when attempting to use a pointer to data member when including the global namespace qualifier on the struct. I've reduced my code to the following, which works:
namespace foo {
using sausage = int;
struct bar { sausage baz; };
}
auto chuckle(foo::bar barry, ::foo::sausage foo::bar::*paul) {
return barry.*paul;
}
int main() {
return chuckle(foo::bar{5}, &foo::bar::baz);
}
If I now add the global namespace qualifier to the bar
struct in the argument to chuckle
:
auto chuckle(foo::bar barry, ::foo::sausage ::foo::bar::*paul) {
// ^~ added ::
return barry.*paul;
}
...then it no longer compiles and fails with the following error:
10 : <source>:10:37: error: 'foo::sausage' is not a class, namespace, or enumeration
auto chuckle(foo::bar barry, ::foo::sausage ::foo::bar::*paul) {
^~~~~~~
10 : <source>:10:57: error: expected identifier before '*' token
auto chuckle(foo::bar barry, ::foo::sausage ::foo::bar::*paul) {
^
<source>: In function 'auto chuckle(foo::bar, int*)':
11 : <source>:11:17: error: 'paul' cannot be used as a member pointer, since it is of type 'int*'
return barry.*paul;
^~~~
<source>: In function 'int main()':
15 : <source>:15:45: error: cannot convert 'foo::sausage foo::bar::* {aka int foo::bar::*}' to 'int*' for argument '2' to 'auto chuckle(foo::bar, int*)'
return chuckle(foo::bar{5}, &foo::bar::baz);
^
I see this behaviour across MSVC, Clang and GCC.
I've put both examples on Godbolt:
a) Why does adding the global namespace qualifier cause the compilation to fail?
b) Is there a reason for this in the language specification?
Subtle issue!
The compiler does not consider extra whitespace, so your code is actually:
auto chuckle(foo::bar barry, ::foo::sausage::foo::bar::*paul)
... which, of course, does not make sense. You need to disambiguate with parentheses:
auto chuckle(foo::bar barry, ::foo::sausage (::foo::bar::*paul))
// ^ ^
... and everything is fine.
If you're not into parentheses, @Paula_plus_plus has you covered with a dummy attribute, which can actually be empty as @T.C. helpfully points out:
auto chuckle(foo::bar barry, ::foo::sausage [[]] ::foo::bar::*paul)
// ^^^^
The compiler is required to ignore it silently, but it does solve the problem for the parser.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With