I have the following piece of C++17 code:
template <typename Callback = void(*)()>
struct A {
A(Callback c = &noop) {}
private:
static void noop() {}
};
int main() {
A a{};
}
Clang 6 compiles this without any errors, but GCC 8.2 says:
In function ‘A(Callback)-> A<Callback> [with Callback = void (*)()]’:
3:24: error: ‘static void A<Callback>::noop() [with Callback = void (*)()]’ is private within this context
A(Callback c = &noop) {}
^~~~~
5:14: note: declared private here
static void noop() {}
^~~~
Interestingly, if Callback
is not a template argument but a simple type alias (i.e. if I write using Callback = void (*)()
inside of the A
class), both compilers are fine. Also, if instead of A a{};
I explicitly write A<> a{};
, both compilers are again fine. This leads me to think that this problem is somehow connected to the new C++17 class template deduction mechanism.
My question is, which of the compilers is right according to the standard? Is this a GCC bug or is Clang being too permissive?
CTAD notionally proceeds by synthesizing a set of functions and function templates ([over.match.class.deduct]p1). As relevant here, the set includes :
If
C
is defined, for each constructor ofC
, a function template with the following properties:
- The template parameters are the template parameters of
C
followed by the template parameters (including default template arguments) of the constructor, if any.- The types of the function parameters are those of the constructor.
- The return type is the class template specialization designated by
C
and template arguments corresponding to the template parameters ofC
.
Notably, this omits default function arguments. This is almost certainly a defect.
Unfortunately, this defect also means that nobody knows from the standard how access control works for the default function arguments of the synthesized function templates - it doesn't even permit them to exist in the first place.
From a design perspective, I'd expect Clang's behavior to be correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With