cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2848 [temp.explicit] Allowing omitting empty template argument list for default arguments during explicit instantiation #489

Closed ranaanoop closed 2 months ago

ranaanoop commented 5 months ago

Full name of submitter: Anoop Rana

Reference (section label): [temp.explicit]

Issue description: Currently the wording in [temp.explicit] does not allow for empty <> to be omitted when all of the template arguments can be obtained from the default arguments. Additionally, it also does not allow for the trailing template argument to be left unspecified if it can be obtained from default argument. The below example shows the issue:

template<class T> class Array { /* ... */ };
template<class T, typename U = double> void sort(Array<T>& v) { /* ... */ }
template void sort<>(Array<int>&);    //ill-formed as per current wording 
template void sort(Array<double>&);   //ill-formed as per current wording

The current wording in temp.explicit#8 states:

A trailing template-argument can be left unspecified in an explicit instantiation of a function template specialization or of a member function template specialization provided it can be deduced ([temp.deduct.decl]). If all template arguments can be deduced, the empty template argument list <> may be omitted.

Suggested resolution:

Change [temp.explicit#8] to as indicated/highlighted below:

A trailing template-argument can be left unspecified in an explicit instantiation of a function template specialization or of a member function template specialization provided it can be deduced ([temp.deduct.decl]). or obtained from default template-arguments. If all template arguments can be deduced or obtained from default template-arguments, the empty template argument list <> may be omitted.

After the suggested changes, the two statements(involving explicit instantiation) will be well-formed.

jensmaurer commented 5 months ago

The entire paragraph seems redundant, given https://eel.is/c++draft/temp.arg.explicit#4 and the preceding p3 which talks about explicit instantiations.

ranaanoop commented 5 months ago

@jensmaurer Yes, It(temp.explicit#8) does seem redundant. Maybe we should remove that paragraph and just update the example given there to as shown below. This can be then editorial perhaps.

template<class T> class Array { /* ... */ };
template<class T, typename U = double> void sort(Array<T>& v) { /* ... */ }
// instantiate void sort<int, double>(Array<int>&) -- template-argument deduced and defaulted
template void sort<>(Array<int>&);
// instantiate void sort<double, double>(Array<double>&) -- template-argument deduced and defaulted
template void sort(Array<double>&); 
jensmaurer commented 5 months ago

CWG2848