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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template <typename I>
class BigUnsigned{
    const size_t cell_size=sizeof(I);
    std::vector _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: warning: friend declaration
'std::ostream& operator<<(std::ostream&, const BigUnsigned&)' declares a non-template function [-Wnon-template-friend] friend std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu); ^ ../hw06/bigunsigned.h:13:77: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) ../hw06/bigunsigned.h:16:51:
error: invalid use of template-name 'BigUnsigned' without an argument
list std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu){ ^ ../hw06/bigunsigned.h: In function 'std::ostream& operator<<(std::ostream&, const int&)': ../hw06/bigunsigned.h:17:28: error: request for member '_integers' in 'bu', which is of non-class type 'const int' for (auto integer : bu._integers){ ^

当我加入这样的声明和定义时,一切都很好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <typename I>
class BigUnsigned{
    const size_t cell_size=sizeof(I);
    std::vector _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;
    }
};

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

附言:使用这个问题,我使函数免费,但没有帮助。


BigUnsigned是模板类型,因此

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

不工作,因为没有BigUnsigned。你需要让friend函数成为一个模板,这样你就可以使用不同类型的BigUnsigned

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename I>
class BigUnsigned{
    const size_t cell_size=sizeof(I);
    std::vector _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;
}

第二个示例之所以有效,是因为它是在类内声明的,所以它使用类使用的模板类型。


纳撒诺利弗对答案的提炼。

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

operator<< BigUnsignedBigUnsignedfriend

operator<< BigUnsignedBigUnsignedfriend

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

operator<< BigUnsignedfriend而不是BigUnsignedfriend

operator<< BigUnsignedfriend而不是BigUnsigned

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 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& bu);

// Change the friend-ship declaration in the class template.
template <typename I>
class BigUnsigned{
    const size_t cell_size=sizeof(I);
    std::vector _integers;
public:
    BigUnsigned();
    BigUnsigned(I);

    // Grant friend-ship only to a specific instantiation of the
    // function template.
    friend std::ostream& operator<< (std::ostream& out, const BigUnsigned& bu);
};


要添加第三个稍微提高可读性的变量,需要在类内定义friend函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#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 << '
'
;
}