Recently a related question was asked Can a friend function in C++ have a default argument whose type has a private destructor? and received an excellent answer. It seems that private constructor of that type is not less interesting.
Please consider the code:
class U {
public:
U() {}
template<typename T>
friend void foo(T, T = 1) {}
private:
U(int) {}
};
int main() {
foo(U{});
}
Here template friend function foo
has a default argument requiring to call private constructor U(int)
.
Since default arguments are bound at the point of declaration, and their access is checked at that point rather than at any points of use of the default argument, the program should be well formed. And GCC accepts the program, while both Clang and MSVC reject it with the error:
error: calling a private constructor of class 'U'
friend void foo(T, T = 1) {}
^
<source>:11:5: note: in instantiation of default function argument expression for 'foo<U>' required here
foo(U{});
^
<source>:7:5: note: declared private here
U(int) {}
^
Demo: https://gcc.godbolt.org/z/bPTGYvnx1
Probably template friend functions behave somewhat differently as to access checking. Which of the compilers is right here?