xtofl
xtofl

Reputation: 41509

friend function template with default template argument

Is it allowed to provide a default to a template argument in a friend declaration?

class A {
    int value;
public:
    template<class T = int> friend void foo();
};

Visual Studio 2015 seems to allow it. gcc refuses it. I couldn't find anything on it on the cppreference page.

Upvotes: 2

Views: 2458

Answers (3)

Nick
Nick

Reputation: 10539

My 5 cents:

In case you are using explicit template instantiation, you can use helper function:

.h file

class A{
    int value;
public:
    template<class T>
    friend void foo_(); // defined in the .cpp file...
};

template<class T = int>
void foo();             // defined in the .cpp file...

.cpp file:

template<class T>
void foo_(){
   //...
}

template<class T>
void foo(){
   return foo_<T>();
}

template void foo<int>();
template void foo<float>();
template void foo<double>();

Note how foo_() can not be called from the client code. Clients will use foo() only.

Upvotes: 0

janosik
janosik

Reputation: 21

If you really want to keep your function foo() global, you can try this:

class A
{
    int value;
public:
    template<class T> friend void foo();
};

template<class T = int> void foo()
{
    //you can use private member of A
    A foo;
    auto value = foo.value;
}

Upvotes: 2

Cubbi
Cubbi

Reputation: 47448

As of C++11, the rule is, specified in 14.1[temp.param]/9

If a friend function template declaration specifies a default template-argument, that declaration shall be a definition and shall be the only declaration of the function template in the translation unit.

Until C++11, of course, 14.1/9 said "A default template-argument shall not be specified in a friend template declaration."

(the above is copied pretty much verbatim, by cppreference at Default template parameters, now also mentioned at Template friends)

So, to make your program valid C++, define your friend template inside the class, don't just declare.

Upvotes: 3

Related Questions