Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to explicitly call a conversion function whose conversion-type-id contains a placeholder specifier

struct A{
  operator auto(){
     return 0;
  }
};
int main(){
   A a;
   a.operator auto(); // #1
   a.operator int(); //  #2
}

GCC accepts that #2 is the right way to call the conversion function explicitly while Clang accepts #1.

It seems that #1 is ill-formed due to the following rule:
dcl.spec.auto#6

A program that uses auto or decltype(auto) in a context not explicitly allowed in this section is ill-formed.

This usage a.operator auto() is not explicitly allowed in section [dcl.spec.auto], hence it should be ill-formed. However, for the second usage, which is accepted by GCC, the standard does not say that the conversion-function-id where the conversion-type-id is replaced by the deduced type denotes the name of the conversion function. In other words, the declared conversion-function-id in the declaration is operator auto rather than operator int. The former has the same token as the declarator-id of the declaration. According to the grammar, the unqualified-id operator auto should be the name of that conversion function. So, how to explicitly call this conversion function? Is it underspecified in the standard about which is the name of the conversion function when it contains a placeholder specifier?

like image 242
xmh0511 Avatar asked Mar 05 '21 02:03

xmh0511


1 Answers

It seems, that this is not specified precisely enough.

  1. From 10.1.7.4 The auto specifier:

The placeholder type can appear with a function declarator in the decl-specifier-seq, type-specifier-seq, conversion-function-id, or trailing-return-type, in any context where such a declarator is valid.

Reading precisely, one might distinguish here between "can" and the stronger "can only", i.e. potentially opening up room for degrees of freedom for compiler intrinsics (strictly wrong vs. unspecified behavior).

And 3.4.5 class member access says:

7 If the id-expression is a conversion-function-id, its conversion-type-id is first looked up in the class of the object expression and the name, if found, is used.

Again leaving room for interpretation if the auto keyword can effectively be a fully qualified conversion-type-id within this context or not.

Your question itself might have to be further branched, namely

  1. What are the overloading rules for the operator auto() usage in detail, i.e. should it be available for regular candidates competition already on class definition level? (not the case for Clang and Gcc, both accept the operator a priori besides an extra operator int() ...)
  2. Can the operator auto() be called with explicit member operator referring (your case 1), i.e. effectively, has it a (unique) accessible name? Allowing that would be contradictory to all other explicitly allowed use cases for the keyword.

I've seen explicit tests for this within several clang revisions so its behavior is not an artefact of implicit naming convention applicance but an explicitly desired behavior obviously.

As already mentioned within the comments, Clang's behavior is a bit more overall consistent here at least in comparison to gcc since it's totally clear there, where the auto keyword is used for type deduction and where for name / function-id resolution. The operator auto() there is handled as a more explicit own entity, whereas for gcc, it has anonymous character similar to a lambda but is involved within candidates competition even for the explicit member operator access way.

like image 136
Secundi Avatar answered Nov 18 '22 18:11

Secundi