Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Templated Class Friend Operator Member Function

I'm trying to get a friend function inside a templated class to compile, but the error message and warning I do not understand. I've made a demonstration of the issue. The error I'm getting is:

prog.cpp:8:57: error: non-class, non-variable partial specialization C operator+(const B& lhs, const C& rhs);

prog.cpp:15:59: warning: friend declaration 'C operator+(const B&, const C&)' declares a non-template function [-Wnon-template-friend] friend C operator+(const B& lhs, const C& rhs);

prog.cpp:15:59: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)

#include <iostream>
using namespace std;

template<typename A, typename B>
class C;

template<typename A, typename B>
C<A, B> operator+<A, B>(const B& lhs, const C<A, B>& rhs);

template<typename A, typename B>
struct C
{
    A val_;
    C operator+(const C& other) const;
    friend C<A, B> operator+(const B& lhs, const C<A, B>& rhs);
};

template<typename A, typename B>
C<A, B> C<A, B>::operator+(const C<A, B>& other) const
{
    C<A, B> c;
    c.val_ = this->val_ + other.val_;
    return c;
}

template<typename A, typename B>
 C<A, B> operator+(const B& lhs, const C<A, B>& rhs)
{
    C<A, B> c;
    c.val_ = lhs + rhs.val_;
    return c;
}

int main() 
{
    C<string, char> c0,c1;
    c0.val_ = " C0 ";
    c1.val_ = " C1 ";
    cout << "Stuct:" << (c0 + c1).val_ << '\n';
    cout << "Friend:" << ('~' + c1).val_ << endl;
    return 0;
}
like image 444
JadziaMD Avatar asked May 02 '16 18:05

JadziaMD


People also ask

What is a templated function?

Function templates. Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.

Can a non templated class have a templated member function?

A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.

Can we declare a template function as the friend of the class?

Many-to-one: All instantiations of a template function may be friends to a regular non-template class. One-to-one: A template function instantiated with one set of template arguments may be a friend to one template class instantiated with the same set of template arguments.

What is a templated class?

Template class. is an instance of a class template. A template definition is identical to any valid class definition that the template might generate, except for the following: The class template definition is preceded by template< template-parameter-list >


1 Answers

The simplest is to inline code inside the class:

template <typename A, typename B>
struct C
{
    A val_;
    C operator+(const C& other) const
    {
        C c;
        c.val_ = this->val_ + other.val_;
        return c;
    }

    friend C operator+ (const B& lhs, const C& rhs)
    {
        C c;
        c.val_ = lhs + rhs.val_;
        return c;
    }
};

Demo

The code not inlined in the class, which requires lot of attention as forward declaration order of declaration, strange syntax <>:

template <typename A, typename B> struct C;

template <typename A, typename B>
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs);

template <typename A, typename B>
struct C
{
    A val_;

    friend C<A, B> operator+<> (const B& lhs, const C<A, B>& rhs);

    C operator+(const C& other) const;
};


template <typename A, typename B>
C<A, B> operator+ (const B& lhs, const C<A, B>& rhs)
{
    C<A, B> c;
    c.val_ = lhs + rhs.val_;
    return c;
}

template <typename A, typename B>
C<A, B> C::operator+(const C<A, B>& other) const
{
    C<A, B> c;
    c.val_ = this->val_ + other.val_;
    return c;
}

Demo

like image 68
Jarod42 Avatar answered Oct 19 '22 05:10

Jarod42