﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-雁过无痕-随笔分类-c++模板</title><link>http://www.cppblog.com/flyinghearts/category/18969.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 30 Mar 2012 12:35:14 GMT</lastBuildDate><pubDate>Fri, 30 Mar 2012 12:35:14 GMT</pubDate><ttl>60</ttl><item><title>安全的整数比较</title><link>http://www.cppblog.com/flyinghearts/archive/2012/03/30/169554.html</link><dc:creator>flyinghearts</dc:creator><author>flyinghearts</author><pubDate>Fri, 30 Mar 2012 12:16:00 GMT</pubDate><guid>http://www.cppblog.com/flyinghearts/archive/2012/03/30/169554.html</guid><wfw:comment>http://www.cppblog.com/flyinghearts/comments/169554.html</wfw:comment><comments>http://www.cppblog.com/flyinghearts/archive/2012/03/30/169554.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/flyinghearts/comments/commentRss/169554.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/flyinghearts/services/trackbacks/169554.html</trackback:ping><description><![CDATA[<br />前几天在水母上看到的题：<br /><br /><div>正常的比较 assert(-1 &lt; 1U) 是会失败的。因为 -1 会提升成无符号数。<br />写一个安全的比较函数，使得<br />template &lt;typename T1, typename T2&gt;<br />int SafeIntCompare(T1 i1, T2 i2);<br />如果 i1 真实值 &lt;&nbsp; i2，返回 -1<br />&nbsp;&nbsp;&nbsp;&nbsp; i1 真实值 == i2，返回&nbsp; 0<br />&nbsp;&nbsp;&nbsp;&nbsp; i1 真实值 &gt;&nbsp; i2，返回&nbsp; 1</div><br /><br />只有当两个类型一个是有符号、另一个是无符号时，才需要特殊处理。<br />对类型的符号判断，可以直接判断该类型的-1是否比0小，也可以用标准库std::numeric_limits&lt;T&gt;中的is_signed成员。<br /><br />简单的做法：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T1&nbsp;v1,&nbsp;T2&nbsp;v2)<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;t1&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;std::numeric_limits</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T1</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::is_signed;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;t2&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;std::numeric_limits</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::is_signed;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(t1&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;t2)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(t1&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;v1&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(t2&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;v2&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(v1&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;v2)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(v1&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;v2)&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />}</span></div><br /><div>但由于进行比较的两个数可能分别是：有符号数和无符号数，编译时编译器会给出大量的警告。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 要避免有符号数和无符号数的进行直接比较，就必须将它们都转为同一个类型T。这个类型的确定可以采用两种方法：<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 1 比较原来两个类型是否是有符号数以及它们所占用的字节数，来推断出应该将它们都转为哪种类型T，这是vc那个safeint的做法。<br /><br />&nbsp; &nbsp;&nbsp; 2 采用这个trick：将这两个类型的数（数可以取0）直接相加，得到的结果的类型就是所求的。这是因为：两个数进行比较时，采用的类型转换规则和两个数相加时所采用的规则是一致的。<br /><br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><img id="Code_Closed_Image_195336" onclick="this.style.display='none'; Code_Closed_Text_195336.style.display='none'; Code_Open_Image_195336.style.display='inline'; Code_Open_Text_195336.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" height="16" width="11" align="top"><img id="Code_Open_Image_195336" style="display: none" onclick="this.style.display='none'; Code_Open_Text_195336.style.display='none'; Code_Closed_Image_195336.style.display='inline'; Code_Closed_Text_195336.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" height="16" width="11" align="top"><span id="Code_Closed_Text_195336" style="border-right: #808080 1px solid; border-top: #808080 1px solid; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">改成后的代码</span><span id="Code_Open_Text_195336" style="display: none"><br /><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; "><br /><br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Assert&nbsp;{};<br />template</span><span style="color: #000000; ">&lt;&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Assert</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">;<br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;is_first_negtive,&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;is_second_negtive</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;SafeIntCmpImpl<br />{<br />&nbsp;&nbsp;template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;int_cmp(T1&nbsp;v1,&nbsp;T2&nbsp;v2)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(v1&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;v2)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(v1&nbsp;&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;v2)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;}<br />};<br /><br />template</span><span style="color: #000000; ">&lt;&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;SafeIntCmpImpl</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />{<br />&nbsp;&nbsp;template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2,&nbsp;typename&nbsp;T3</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;int_cmp(T1&nbsp;v1,&nbsp;T2&nbsp;v2,&nbsp;T3)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;SafeIntCmpImpl</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::int_cmp(T3(v1),&nbsp;T3(v2));<br />&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;int_cmp(T1&nbsp;v1,&nbsp;T2&nbsp;v2)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;v1&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;:&nbsp;int_cmp(v1,&nbsp;v2,&nbsp;T1(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;T2(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">));<br />&nbsp;&nbsp;}<br />};<br /><br />template</span><span style="color: #000000; ">&lt;&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;SafeIntCmpImpl</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />{<br />&nbsp;&nbsp;template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;int_cmp(T1&nbsp;v1,&nbsp;T2&nbsp;v2)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">SafeIntCmpImpl</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::int_cmp(v2,&nbsp;v1);<br />&nbsp;&nbsp;}<br />};<br /><br /><br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T1&nbsp;v1,&nbsp;T2&nbsp;v2)<br />{<br />&nbsp;&nbsp;typedef&nbsp;std::numeric_limits</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T1</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;M1;<br />&nbsp;&nbsp;typedef&nbsp;std::numeric_limits</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;M2;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;is_arg_valid&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;M1::is_integer&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;M2::is_integer;<br />&nbsp;&nbsp;Assert</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">is_arg_valid</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">();<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;SafeIntCmpImpl</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">M1::is_signed,&nbsp;M2::is_signed</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">::int_cmp(v1,&nbsp;v2);<br />}<br /></span></span></div><br />&nbsp; 但上面的写法有一个问题：如果一个 short和一个unsigned char进行比较，编译器都是转为int进行比较，没有必要进行特殊处理（上面的代码处理后会多一个与0的比较）。实际上，如果两个类型都是转为有符号类型，可以直接进行比较。</div>最终代码：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; "><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;IsSigned&nbsp;{&nbsp;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;value&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;T(</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;T(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);&nbsp;<br />};<br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Assert&nbsp;{};<br />template</span><span style="color: #000000; ">&lt;&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Assert</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">;<br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;Type&nbsp;{};<br />typedef&nbsp;Type</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;TagNormal;<br />typedef&nbsp;Type</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;TagFirstArgIsSigned;<br />typedef&nbsp;Type</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;TagSecondArgIsSigned;<br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2,&nbsp;typename&nbsp;T3</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T1&nbsp;v1,&nbsp;T2&nbsp;v2,&nbsp;T3,&nbsp;TagNormal)<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(v1&nbsp;&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;v2)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(v1&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;v2)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />}<br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2,&nbsp;typename&nbsp;T3</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T1&nbsp;v1,&nbsp;T2&nbsp;v2,&nbsp;T3&nbsp;v3,&nbsp;TagFirstArgIsSigned)<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(v1&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T3(v1),&nbsp;T3(v2),&nbsp;v3,&nbsp;TagNormal());<br />}<br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2,&nbsp;typename&nbsp;T3</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T1&nbsp;v1,&nbsp;T2&nbsp;v2,&nbsp;T3&nbsp;v3,&nbsp;TagSecondArgIsSigned)<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(v2&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T3(v1),&nbsp;T3(v2),&nbsp;v3,&nbsp;TagNormal());<br />}<br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2,&nbsp;typename&nbsp;T3</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T1&nbsp;v1,&nbsp;T2&nbsp;v2,&nbsp;T3&nbsp;v3)<br />{<br />&nbsp;&nbsp;typedef&nbsp;std::numeric_limits</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T1</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;M1;<br />&nbsp;&nbsp;typedef&nbsp;std::numeric_limits</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;M2;<br />&nbsp;&nbsp;typedef&nbsp;std::numeric_limits</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">T3</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;M3;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">bool</span><span style="color: #000000; ">&nbsp;is_arg_valid&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;M1::is_integer&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;M2::is_integer;<br />&nbsp;&nbsp;Assert</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">is_arg_valid</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">();<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;type_idx&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;M3::is_signed&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;:&nbsp;(M1::is_signed&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;M2::is_signed&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">2</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">%</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">3</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;SafeIntCompare(v1,&nbsp;v2,&nbsp;v3,&nbsp;Type</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">type_idx</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">());<br />}<br /><br /><br />template</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">typename&nbsp;T1,&nbsp;typename&nbsp;T2</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;SafeIntCompare(T1&nbsp;v1,&nbsp;T2&nbsp;v2)<br />{<br />&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;SafeIntCompare(v1,&nbsp;v2,&nbsp;T1(</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;T2(</span><span style="color: #000000; ">0</span><span style="color: #000000;">));<br />}<br /></span></div><img src ="http://www.cppblog.com/flyinghearts/aggbug/169554.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/flyinghearts/" target="_blank">flyinghearts</a> 2012-03-30 20:16 <a href="http://www.cppblog.com/flyinghearts/archive/2012/03/30/169554.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>