﻿<?xml version='1.0' encoding='UTF-8'?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Релиб / Программирование / C++  / Насколько сложно определить шаблон функции-друга для шаблона класса / Latest Posts</title><generator>InstantForum.NET v4.1.4</generator><description>Релиб</description><link>http://www.relib.com/forums/</link><webMaster>robot@relib.com</webMaster><lastBuildDate>Thu, 20 Nov 2008 00:27:15 GMT</lastBuildDate><ttl>20</ttl><item><title>Насколько сложно определить шаблон функции-друга для шаблона класса</title><link>http://www.relib.com/forums/Topic908699-7-1.aspx</link><description>У меня есть класс типа :[code]&lt;DIV class=codemain style="OVERFLOW: auto; WHITE-SPACE: pre; HEIGHT: 200px"&gt;template &amp;lt;class T&amp;gt;&lt;BR&gt;class array &lt;BR&gt;{&lt;BR&gt;...&lt;BR&gt;    friend std::ostream&amp;amp; operator&amp;lt;&amp;lt; &lt;BR&gt;        (&lt;BR&gt;            std::ostream&amp;amp; output,&lt;BR&gt;            const array&amp;lt;T&amp;gt;&amp;amp;&lt;BR&gt;        );&lt;BR&gt;...&lt;BR&gt;}; &lt;/DIV&gt;&lt;P&gt;[/code]&lt;/P&gt;&lt;P&gt;(Полный код в аттачменте - это слегка модифицированный пример 19.4 из книжки Джеса Либерти "Освой самостоятельно C++ за 21 день". Я компилил Visual C++ 13.10.3077 (VS2003) компилятором с ключами /EHsc /Zc:forScope. Обратите внимание, что если вводить исходные данные таким образом, что вместо двух цифр ввести одну, а потом сразу делимитер (пробел, таб, запятая, семиколон или точка), то функция std::string::at () вызывает out of range exception, и программа падает)&lt;/P&gt;&lt;P&gt;Проблема в том, что если определить объявленный другом класса array operator&amp;lt;&amp;lt; как шаблон функции следующим образом:&lt;BR&gt;[code]template &amp;lt;class T&amp;gt;&lt;BR&gt;std::ostream&amp;amp; operator&amp;lt;&amp;lt; &lt;BR&gt;    (&lt;BR&gt;        std::ostream&amp;amp; output,&lt;BR&gt;        const array&amp;lt;T&amp;gt;&amp;amp; rhs&lt;BR&gt;    ) &lt;BR&gt;{&lt;BR&gt;    // loop invariant: the first i + 1 members of array&lt;BR&gt;    // put into output buffer &lt;BR&gt;    for (int i = 0; i &amp;lt; rhs.getSize (); ++i)&lt;BR&gt;        output &amp;lt;&amp;lt; '[' &amp;lt;&amp;lt; i &lt;BR&gt;            &amp;lt;&amp;lt; "] " &amp;lt;&amp;lt; rhs[i] &amp;lt;&amp;lt; std::endl;&lt;BR&gt;    return output;&lt;BR&gt;}[/code],&lt;BR&gt;т.е. чтобы он мог вызываться для любого экземпляра класса array, то программа компилируется, но не линкуется. Сообщение компоновщика следующее:&lt;BR&gt;[quote]&lt;FONT face="Courier New"&gt;List19_4.obj : error LNK2019: unresolved external symbol "class std::basic_ostream&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt; &amp;gt; &amp;amp; __cdecl operator&amp;lt;&amp;lt;(class std::basic_ostream&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt; &amp;gt; &amp;amp;,class array&amp;lt;class animal&amp;gt; const &amp;amp;)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$array@Vanimal@@@@@Z) referenced in function _main&lt;BR&gt;List19_4.obj : error LNK2019: unresolved external symbol "class std::basic_ostream&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt; &amp;gt; &amp;amp; __cdecl operator&amp;lt;&amp;lt;(class std::basic_ostream&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt; &amp;gt; &amp;amp;,class array&amp;lt;int&amp;gt; const &amp;amp;)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$array@H@@@Z) referenced in function _main&lt;BR&gt;Debug/List19_4.exe : fatal error LNK1120: 2 unresolved externals&lt;/FONT&gt;&lt;BR&gt;[/quote]В результате я закомментил в файле вышеуказонное определение шаблона оператора &amp;lt;&amp;lt; и просто определил два перегруженных оператора &amp;lt;&amp;lt; - для параметра array&amp;lt;int&amp;gt; и для array&amp;lt;animal&amp;gt; соответственно. А как правильно определить именно шаблон для оператора &amp;lt;&amp;lt; чтобы работал с любым array&amp;lt;T&amp;gt;?</description><pubDate>Fri, 08 Dec 2006 21:56:40 GMT</pubDate><dc:creator>Blob</dc:creator></item></channel></rss>