The following code
struct some{};
some thingy;
#ifdef OH
template<typename W>
#endif
struct Wrapper
{
template<typename S>
struct Checker
{
Checker(S &) {}
};
template<typename S>
friend
void check(S& strm, Wrapper const&)
{
Checker{strm}; // line 19
}
};
int main()
{
Wrapper
#ifdef OH
<int>
#endif
w;
check( thingy, w );
}
compiles with GCC 12 and clang 14, as long as Wrapper is not a template.
If Wrapper is a template (-DOH
switch), then GCC keeps accepting the code, but clang complains that it can't find a constructor or deduction guide.
<source>:19:9: error: no viable constructor or deduction guide for deduction of template arguments of 'Checker'
Checker{strm};
^
<source>:31:5: note: in instantiation of function template specialization 'check<some>' requested here
check( thingy, w );
^
<source>:10:12: note: candidate template ignored: could not match 'Checker<S>' against 'some'
struct Checker
^
<source>:10:12: note: candidate function template not viable: requires 0 arguments, but 1 was provided
1 error generated.
https://godbolt.org/z/oTTKEcdfe
The difference in clang's behavior between the templated vs non-templated wrapper class is surprising to me. I would have expected the same behavior in both cases (like GCC). Is this a bug, a QoI issue or something allowed by the standard (and hopefully not UB)?