正确声明模板化运算符<<(basic_ostream< charT、特征>、myClass<T > ) 作为朋友
Correctly declaring templated operator<<( basic_ostream< charT, traits >, myClass< T > ) as a friend
我正在尝试提高对模板的理解。作为测试,我想超载流operator<<
,以便它将在模板类上与STL的(模板)basic_ostream
一起运行。这是一个最小示例:
#include <iostream>
using namespace std;
//Forward declarations
template< typename T >
class Container;
template< typename T, typename charT, typename traits >
basic_ostream< charT, traits >&
operator<<( basic_ostream< charT, traits >& out,
const Container< T >& a_container );
//Definitions
template< typename T >
class Container
{
public:
Container( T a_value ): value( a_value ){}
private:
T value;
template< typename charT, typename traits >
friend basic_ostream< charT, traits >&
operator<<( basic_ostream< charT, traits >& out,
const Container< T >& a_container );
};
template< typename T, typename charT, typename traits >
basic_ostream< charT, traits >&
operator<<( basic_ostream< charT, traits >& out,
const Container< T >& a_container )
{
out << a_container.value;
return out;
}
//Main
int main( void )
{
Container< int > my_container( 42 );
cout << my_container;
return 0;
}
但是,当我尝试编译此代码时,链接器似乎找不到超载函数:
/home/Ae6PGM/cc5xj2iM.o: In function `main':
prog.cpp:(.text.startup+0x21): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& operator<< <char, std::char_traits<char> >
(std::basic_ostream<char, std::char_traits<char> >&, Container<int> const&)'
collect2: error: ld returned 1 exit status
如果我将operator<<
过载的每个模板实例作为朋友,我可以解决此错误,但是只有与容器类型匹配的实例是朋友,这似乎更正确。这是工作的链接,但不正确的方面:http://ideone.com/dnqzlb。
另一种选择是将函数定义放置在类声明中,但是如果可能的话,我想避免使用。
这里有一个类似但更简单的问题。有一个很好的答案,但我不知道如何适应我的问题。
谢谢,
安德鲁
模板的原始声明采用了三个模板参数{ T, charT, traits }
,但friend
声明仅占2 { charT, traits }
。您将获得一个不确定的参考,因为编译器将其视为两个单独的功能,其中一个尚未定义。
您需要给它一个第三模板参数:
template< typename T2, typename charT, typename traits > friend basic_ostream< charT, traits >& operator<< ( basic_ostream< charT, traits >& out, const Container< T2 >& a_container );
谢谢您问这个问题。我通过审查它学到了很多。
也就是说,我想我理解您要问什么。如果我正确理解您,您将尝试通过您的功能模板实现和控制隐式实例。
尽管您在此处发布的示例是operator<<
Overloading,但对于函数模板实现了此通用编程的基础机制是相同的。
陈述cout << my_container
时,您正在实例化的是过载的operator<<
。但是,如果要实例化非模板流对象,则必须修改要从中读取的内容。
由于类数据成员值是私有的,因此您可以使用指针明确指向该数据成员,并使用该指针实例化非网板流对象。以以下示例查看:
int* private_value = (int*)&my_container;
尽管封装,*private_value
应该允许您访问私人成员。
如果要增强数据成员的安全性,则需要更深入的封装以防止这种实现。
模板参数可以通过包括get()
函数并访问value
来实现(如果是您正在寻找的话),从而实例化了非template流对象。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中