首页 文章

模板类朋友操作员成员函数

提问于
浏览
8

我正在尝试在模板化的类中获取一个朋友函数来编译,但错误消息和警告我不明白 . 我已经证明了这个问题 . 我得到的错误是:

prog.cpp:8:57:错误:非类,非可变部分特化C运算符(const B&lhs,const C&rhs); prog.cpp:15:59:警告:朋友声明'C运算符(const B&,const C&)'声明一个非模板函数[-Wnon-template-friend]朋友C运算符(const B&lhs,const C&rhs); prog.cpp:15:59:注意:(如果这不是你想要的,请确保已经声明了函数模板,并在函数名后添加<>)

#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;
}

2 回答

  • 3

    本声明:

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

    ......因为 operator+( 之间的 <A,B> 错了,我真的不知道你想做什么 . 如果你要专门化一个模板化的 operator+ ,你会使用这个表格,但你不在这里,你正在超载一个 .

    该声明应为:

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

    那么你应该在你的 friend 声明中明确指出你想要一个专门的版本:

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

    你需要把它放在你的 operator+ 之前,编译器会认为这是非模板化函数的特化 .

    无论如何,如果你没有真正的理由将你的代码放在 C 类之外,我会去@ Jarod42解决方案 .


    您的整个代码应如下所示:

    // Declaration of struct C with delayed definition
    template <typename A, typename B>
    struct C;
    
    // Initial declaration of templated operator+
    template <typename A, typename B>
    C<A, B> operator+ (const B&, const C<A, B>&);
    
    // Definition of C
    template <typename A, typename B>
    struct C {
    
        friend C operator+<> (const B&, const C&);
    
        // This must be AFTER the templated operator+
        C operator+ (const C&) const;
    };
    
    template<typename A, typename B>
    C<A, B> C<A, B>::operator+(const C<A, B>& other) const {
    
    }
    
    template<typename A, typename B>
    C<A, B> operator+(const B& lhs, const C<A, B>& rhs) {
    
    }
    
  • 5

    最简单的是在类中内联代码:

    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

    代码没有在类中内联,这需要很多关注作为声明的前向声明顺序,奇怪的语法 <>

    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

相关问题