gpt4 book ai didi

c++ - 如何在类声明之外声明泛型类的友元?

转载 作者:太空狗 更新时间:2023-10-29 19:59:58 26 4
gpt4 key购买 nike

以下代码有效,但我想将 ostream& operator<< 移到类声明之外,就像我对 hash::operator[] 所做的那样。

#include<iostream>
#include<map>

using namespace std;

template <class T>
class hash {
private:
map<string, T> _map;
public:
T& operator[] (string x);
friend ostream& operator<<(ostream& out, const hash<T> &rhs) { return out << "test"; }
};

template <class T>
T & hash<T>::operator[](string x) {
return _map[x];
}

int main () {
hash<int> myobject;
myobject["a"] = 1;
cout << myobject["a"] << endl;
cout << myobject << endl;
return 0;
}

我试过:

template <class T>
ostream& operator<<(...) {
return out << "test";
}

ostream& operator<<(...) {
return out << "test";
}

以及其他一些组合都无济于事。

最佳答案

由于这个问题似乎并没有完全重复,所以我将解释您的程序的作用。

template <typename T>
class test {
int private_field;
friend std::ostream& operator<<( std::ostream&, test<T> const & );
};
// ???
int main() {
std::cout << test<int>() << std::endl;
}

模板是按需实例化的(除非您明确实例化它们),这意味着在这个特定程序中 test仅实例化为 test<int> .当编译器实例化模板时(因为它是在 main 中请求的),它将处理模板定义。此时的行为类似于在定义点用替换类型重写代码(在本例中就在 main 之前):

class test<int> {
friend std::ostream& operator<<( std::ostream&, test<int> const & );
};

现在,如果您查看实例化模板,您会注意到 friend声明正在帮助一个非模板函数。所以在这个特定的程序中,您可以填写 ???具有该特定功能:

std::ostream& operator<<( std::ostream& o, test<int> const & t ) {
return o << t.private_field;
}

这里的问题是这不容易扩展。那个operator<<的代码与 test<int> 相同比test<double> ,所以应该没有必要为所有实例化类型重写相同的函数!

此时有两个选项,第一个是,正如您已经确定的那样,在类内部提供函数的定义。每当类型被实例化时,编译器将处理和定义函数。该解决方案根据需要为每个模板实例化创建非模板函数(这是我会做的选项,即使这里的查找有怪癖和奇怪之处)。

现在,如果你真的想避免在模板类中提供定义,并且你仍然想提供一个单一的实现,那么你必须求助于提供模板 operator<< .此时你有两个不同的选择,你可以声明模板的所有实例化(我不太喜欢,因为它向太多其他人开放),或者你可以与模板函数(关于访问更清晰,编写起来更麻烦)。

第一种情况是:

template <typename T>
class test {
template <typename U>
friend std::ostream& operator<<( std::ostream&, test<U> const & );
};
template <typename T>
std::ostream& operator<<( std::ostream&, test<T> const & ) { ... }

第二种情况需要几个前向声明:

template <typename T> test;
template <typename T> std::ostream& operator<<( std::ostream&, test<T> const & );
template <typename T>
class test {
friend std::ostream& operator<< <T>( std::ostream&, const test<T>& );
};
template <typename T>
std::ostream& operator<<( std::ostream&, test<T> const & ) { ... }

当然还有另一种选择:不声明friend完全没有。提供print(std::ostream&)具有实现的类中的公共(public)函数,并提供非模板化 operator<<只是调用print关于第二个论点。

关于c++ - 如何在类声明之外声明泛型类的友元?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9754615/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com