Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

incomplete class usage with auto in template class

Is the following code well formed ?

class B;

template<class T>
class A
{
    B do_f() const;
    friend auto f(A const& a) {return a.do_f();} // #1
};

class B{};

template <class T>
B A<T>::do_f() const { return B{};}

int main()
{
    A<double> a;
    f(a);
}

If I change auto in #1 by B, I got incomplete type error message.

Compile with auto for gcc/clang Demo

Fail with B Demo

like image 874
Jarod42 Avatar asked Oct 10 '18 23:10

Jarod42


1 Answers

[dcl.fct.def.general]/2:

The type of a parameter or the return type for a function definition shall not be an incomplete or abstract (possibly cv-qualified) class type in the context of the function definition unless the function is deleted ([dcl.fct.def.delete]).

But [dcl.spec.auto]/10:

Return type deduction for a function template with a placeholder in its declared type occurs when the definition is instantiated even if the function body contains a return statement with a non-type-dependent operand.

So with B, it's ill-formed by the first rule. But with auto, deduction doesn't take place until the function is instantiated... by which point the type is complete, so it's fine.

Note that the first rule only applies to the definition, which is why do_f() is okay. You can have declarations which return incomplete types.


The above wording technically doesn't apply to this case. We don't have a function template. But the intent is for it to apply to any kind of templated thing. There's a PR to editorially fix this from:

Return type deduction for a function template with a placeholder [...]

To:

Return type deduction for a templated entity that is a function or function template with a placeholder in its

Which does apply here.

like image 195
Barry Avatar answered Oct 24 '22 04:10

Barry