- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试为返回流的二叉树实现一个方法。我想使用方法中返回的流在屏幕上显示树或将树保存在文件中:
这两个方法在二叉树的类中:
声明:
void streamIND(ostream&,const BinaryTree<T>*);
friend ostream& operator<<(ostream&,const BinaryTree<T>&);
template <class T>
ostream& operator<<(ostream& os,const BinaryTree<T>& tree) {
streamIND(os,tree.root);
return os;
}
template <class T>
void streamIND(ostream& os,Node<T> *nb) {
if (!nb) return;
if (nb->getLeft()) streamIND(nb->getLeft());
os << nb->getValue() << " ";
if (nb->getRight()) streamIND(nb->getRight());
}
此方法在 UsingTree 类中:
void UsingTree::saveToFile(char* file = "table") {
ofstream f;
f.open(file,ios::out);
f << tree;
f.close();
}
所以我重载了 BinaryTree 类的运算符“<<”以使用:cout << tree 和 ofstream f << tree,但我收到下一条错误消息:undefined reference to `operator<<(std::basic_ostream >&, 二叉树&)'
附言树存储 Word 对象(带有 int 的字符串)。
我希望你能理解我糟糕的英语。谢谢!我想知道一本适合初学者的关于 STL 的好书,它解释了所有必要的内容,因为我把所有的时间都浪费在了这样的错误上。
编辑:声明 saveToFile() 中的树:BinaryTree< Word > 树。
最佳答案
问题是编译器没有尝试使用模板化的 operator<<
你提供的,而是一个非模板版本。
当您在类中声明一个友元时,您是在封闭范围内注入(inject)该函数的声明。以下代码具有声明(而不是定义)一个采用 non_template_test
的自由函数的效果。通过常量引用论证:
class non_template_test
{
friend void f( non_template_test const & );
};
// declares here:
// void f( non_template_test const & );
模板类也会发生同样的情况,即使在这种情况下它不太直观。当您在模板类主体中声明(而不是定义)一个友元函数时,您是在声明一个具有该确切参数的自由函数。请注意,您声明的是函数,而不是模板函数:
template<typename T>
class template_test
{
friend void f( template_test<T> const & t );
};
// for each instantiating type T (int, double...) declares:
// void f( template_test<int> const & );
// void f( template_test<double> const & );
int main() {
template_test<int> t1;
template_test<double> t2;
}
那些自由函数被声明但没有被定义。这里棘手的部分是那些自由函数不是模板,而是声明的常规自由函数。当您将模板函数添加到组合中时,您会得到:
template<typename T> class template_test {
friend void f( template_test<T> const & );
};
// when instantiated with int, implicitly declares:
// void f( template_test<int> const & );
template <typename T>
void f( template_test<T> const & x ) {} // 1
int main() {
template_test<int> t1;
f( t1 );
}
当编译器命中主函数时,它会实例化模板 template_test
与类型 int
并且声明了自由函数 void f( template_test<int> const & )
那不是模板化的。当它发现调用 f( t1 )
有两个f
匹配的符号:非模板f( template_test<int> const & )
在 template_test
时声明(但未定义)被实例化,模板化版本在 1
声明和定义.非模板版本优先,编译器匹配它。
当链接器尝试解析 f
的非模板版本时它找不到符号,因此失败。
我们能做什么?有两种不同的解决方案。在第一种情况下,我们让编译器为每个实例化类型提供非模板函数。在第二种情况下,我们将模板化版本声明为友元。它们略有不同,但在大多数情况下是等同的。
让编译器为我们生成非模板函数:
template <typename T>
class test
{
friend void f( test<T> const & ) {}
};
// implicitly
这具有根据需要创建尽可能多的非模板化自由函数的效果。当编译器在模板中找到友元声明时 test
它不仅找到声明,还找到实现并将两者添加到封闭范围。
使模板化版本成为 friend
要使模板成为友元,我们必须已经声明它并告诉编译器我们想要的友元实际上是一个模板,而不是一个非模板化的自由函数:
template <typename T> class test; // forward declare the template class
template <typename T> void f( test<T> const& ); // forward declare the template
template <typename T>
class test {
friend void f<>( test<T> const& ); // declare f<T>( test<T> const &) a friend
};
template <typename T>
void f( test<T> const & ) {}
在这种情况下,在声明 f
之前作为模板,我们必须转发声明模板。申报f
模板我们必须先转发声明test
模板。友元声明被修改为包含尖括号,用于标识我们要成为友元的元素实际上是模板而不是自由函数。
回到问题
回到您的特定示例,最简单的解决方案是让编译器通过内联友元函数的声明为您生成函数:
template <typename T>
class BinaryTree {
friend std::ostream& operator<<( std::ostream& o, BinaryTree const & t ) {
t.dump(o);
return o;
}
void dump( std::ostream& o ) const;
};
使用该代码,您将强制编译器生成一个非模板化的 operator<<
对于每个实例化类型,生成的函数委托(delegate) dump
模板的方法。
关于c++ - 为模板类重载运算符<<,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1810753/
namespace std { template <> class hash{ public : size_t operator()( cons
我正在构建一个 Javascript 交互性有限的 Django 应用程序,并且正在研究如何将 Vue 模板与 Django 模板合并以实现相同的内容。 想象一个无限滚动的页面,其中 SEO 非常重要
我需要一个由游戏逻辑组成的外部类,调用 LitElement 组件,并向其传递一个 html 模板文字,该组件将使用该文字来更新其自己的 html 模板文字的一部分。 在下面的代码中,您将看到组件的一
很简单,我不想在 html 文件中定义所有 Handlebars 模板 我试过了 但这并没有奏效。我是否可以不以编程方式定义模板,甚至只是加载 Handlebars 文件,以便我可以重用,而且我觉得
在此代码中,j 正确地成为对象:j.name、j.addr、j.city、j.state 和 j.zip。但是,成功函数有一个 JavaScript 错误 .tmpl() 不是函数。 {{t
Django模板不会?点进来,总结了模板语法传值取值、过滤器和自定义过滤器、模板标签的分类、中间件403报错如何解决、如何继承模板~👆 Django 模板 模板传值取值 后端传值 键值对形式:{‘n
哈喽大家好,我是鹿 九 丸 \color{red}{鹿九丸}鹿九丸,今天给大家带来的是C++模板。 如果大家在看我的博客的过程中或者学习的过程中以及在学习方向上有什么问题或者想跟我交流的话可以加我的企
我正在用 PHP 编写一个简单的模板层,但我遇到了一些困难。目前它是这样工作的: 首先,我使用 fetch_template 从数据库中加载模板内容 - 这可行(如果您有兴趣,我会在启动时收集所有模板
我正在制作有关模板的 Django 教程。我目前处于此代码: from django.template import Template, Context >>> person = {'name': '
我正在使用 Jquery 模板来显示传入的 JSON 数据我想将模板加载到可缓存的外部文件中。我该怎么做? 更新 http://encosia.com/2010/12/02/jquery-templa
这是我的观点.py: from django.http import HttpResponse from django.template.loader import get_template from
我试图说服一位同事在项目的前端使用 Mustache/Hogan,我提出了以下建议: 有一个 templates.js 文件,大致如下所示: var tpl_alert = '{{msg}}'; va
我想创建一个通用的数组函数。在我的 API 中,我有一个通用容器,我需要将其转换为正确的类,但我想让它通用 template void UT::printArray(CCArray* arr, T t
有谁知道是否有办法在 Genshi 中创建 javascript 模板?我的意思是,我需要一个 .js 文件,可以在其中使用 等指令。等等。 有什么想法吗?谢谢! 最佳答案 你可以直接在html中这
我想知道是否可以设置某种 HTML 模板系统,基本上我有 3 个不同的文件: - header.html - footer.html - landing.html(landing.html 是包含页面
我正在尝试构建以下 HTML 模板: 这很简单,如果我使用红色容器 1-4,语法如下: 1 2 3 4 5 6 7 8 9 https://jsfi
#include "boost/numeric/ublas/matrix.hpp" using namespace boost::numeric::ublas; template class Lay
我在一个类中有一个函数,它传递了一个函数及其参数,然后将它们绑定(bind)到一个函数调用中并调用该函数等。 这已经被快速组合在一起以测试我知道代码不是很好的概念。 class Profiling {
是否有一个 c++ 结构或模板(在任何库中)允许我在十进制和任何其他基数之间进行转换(很像 bitset 可以做的)? 最佳答案 是的,你可以使用unsigned int: unsigned int
数据类型给程序设计带来的困扰及解决方案 int maxt(int, int); double maxt(double, double); 若有一种占位符T,能够代替类型,便可以简化代码的冗余编写
我是一名优秀的程序员,十分优秀!