operator<<(ostream&, const BigUnsigned<I>&) 必须只接受一个参数

operator<<(ostream&, const BigUnsigned<I>&) must take exactly one argument

本文关键字:lt 一个 参数 gt ostream const BigUnsigned operator      更新时间:2023-10-16

我试图将模板化类的模板化成员函数的声明和定义分开,但最终出现以下错误和警告。

template <typename I>
class BigUnsigned{
    const size_t cell_size=sizeof(I);
    std::vector<I> _integers;
public:
    BigUnsigned();
    BigUnsigned(I);
    friend std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu);
};
std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu){
    for (auto integer : bu._integers){
        out<<integer<<std::endl;
    }
    return out;
}

../hw06/bigunsigned.h:13:77:警告:好友声明 'std::ostream& operator<<(std::ostream&, const BigUnsigned&)' 声明一个非模板函数 [-Wnon-template-friend] friend std::ostream& operator<<(std::ostream& out, const BigUnsigned&bu); ^ ../hw06/bigunsigned.h:13:77:注意:(如果这不是你 打算,请确保已声明函数模板 并在此处的函数名称后添加<>)../hw06/bigunsigned.h:16:51: 错误:在没有参数的情况下无效使用模板名称"BigUnsigned" list std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu){ ^ ../hw06/bigunsigned.h:在函数'std::ostream& operator<<(std::ostream&, const int&)': ../hw06/bigunsigned.h:17:28: 错误:请求"bu"中的成员"_integers",这是非类的 键入"常量整数" for (自动整数 : bu._integers){ ^

当我像这样加入声明和定义时,一切都编译得很好。

template <typename I>
class BigUnsigned{
    const size_t cell_size=sizeof(I);
    std::vector<I> _integers;
public:
    BigUnsigned();
    BigUnsigned(I);
    friend std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu){
        for (auto integer : bu._integers){
            out<<integer<<std::endl;
        }
        return out;
    }
};

目的是打印成员变量_integers到cout。可能有什么问题?

PS:使用这个问题,我使该功能免费,但没有帮助。

BigUnsigned是模板类型,因此

std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu)

由于没有BigUnsigned,因此无法正常工作. 您需要将友元函数设置为模板,以便您可以采用不同类型的BigUnsigned<some_type>

template <typename I>
class BigUnsigned{
    const size_t cell_size=sizeof(I);
    std::vector<I> _integers;
public:
    BigUnsigned();
    BigUnsigned(I);
    template<typename T>
    friend std::ostream& operator<<(std::ostream& out, const BigUnsigned<T>& bu);
};
template<typename T>
std::ostream& operator<<(std::ostream& out, const BigUnsigned<T>& bu){
    for (auto integer : bu._integers){
        out<<integer<<std::endl;
    }
    return out;
}

第二个示例起作用的原因是,由于它是在类内部声明的,因此它使用类使用的模板类型。

NathanOliver对答案的改进。

对于另一个答案,函数模板的所有实例化都是类模板的所有实例化的friend

operator<< <int>BigUnsigned<int>BigUnsigned<double>friend

operator<< <double>BigUnsigned<double>BigUnsigned<FooBar> friend

您可以稍微更改声明,以便

operator<< <int>BigUnsigned<int>friend,但不是BigUnsigned<double>

operator<< <double>BigUnsigned<double>friend,但不是BigUnsigned<FooBar>

// Forward declaration of the class template.
template <typename I> class BigUnsigned;
// Forward declaration of the function template
template <typename I>
std::ostream& operator<<(std::ostream& out, const BigUnsigned<I>& bu);
// Change the friend-ship declaration in the class template.
template <typename I>
class BigUnsigned{
    const size_t cell_size=sizeof(I);
    std::vector<I> _integers;
public:
    BigUnsigned();
    BigUnsigned(I);
    // Grant friend-ship only to a specific instantiation of the
    // function template.
    friend std::ostream& operator<< <I>(std::ostream& out, const BigUnsigned<I>& bu);
};

要添加第三个变体来提高可读性,就是在类中定义 friend 函数:

#include <iostream>
template <typename T>
class Foo {
    int test = 42;
    // Note: 'Foo' inside the class body is basically a shortcut for 'Foo<T>'
    // Below line is identical to: friend std::ostream& operator<< (std::ostream &os, Foo<T> const &foo)
    friend std::ostream& operator<< (std::ostream &os, Foo const &foo) {
        return os << foo.test;
    }
};

int main () {
    Foo<int> foo;
    std::cout << foo << 'n';
}
相关文章: