Which one of the compilers is right ?
class A
{
public:
template
void fun(void (*f)() = funPrivate) {}
private:
template
I have tested code in msvc13. This code works:
class A
{
template <typename T>
static void funPrivate() {}
public:
template <typename T>
void fun(void (*f)() = funPrivate<T>) {}
};
§ 11
8 The names in a default argument (8.3.6) are bound at the point of declaration, and access is checked at that point rather than at any points of use of the default argument. Access checking for default arguments in function templates and in member functions of class templates is performed as described in 14.7.1.
§ 14.7.1
12 If a function template
f
is called in a way that requires a default argument to be used, the dependent names are looked up, the semantics constraints are checked, and the instantiation of any template used in the default argument is done as if the default argument had been an initializer used in a function template specialization with the same scope, the same template parameters and the same access as that of the function templatef
used at that point. This analysis is called default argument instantiation. The instantiated default argument is then used as the argument off
.
So, according to this, I would guess that gcc's interpretation is right. fun
has access to private members, so its default arguments should be considered in that same access. But I am reading between the lines that 14.7.1(12) applies to member templates, and not just function templates. Also I may be misunderstanding that 14.7.1(12) means.