首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

《C++ Primer》16.2.2节的有关问题

2012-08-11 
《C++ Primer》16.2.2节的问题描述如下该节主题:函数模板的显示实参在某些情况下,不可能推断模板实参的类型。

《C++ Primer》16.2.2节的问题
描述如下
该节主题:函数模板的显示实参
在某些情况下,不可能推断模板实参的类型。当函数的返回类型必须与形参表中所用的所有类型都不同时,最常出现这一问题。在这种情况下,有必要覆盖模板实参推断机制,并显式指定为模板形参所用的类型或值。

考虑下面的问题。我们希望定义名为 sum、接受两个不同类型实参的函数模板,希望返回类型足够大,可以包含按任意次序传递的任意两个类型的两个值的和,怎样才能做到?应如何指定 sum 的返回类型?

  // T or U as the returntype?
  template <class T, class U> ??? sum(T, U);

在这个例子中,答案是没有一个形参在任何时候都可行,使用任一形参都一定会在某些时候失败:

  // neither T nor U works as return type
  sum(3, 4L); // second type is larger; want U sum(T, U)
  sum(3L, 4); // first type is larger; want T sum(T, U)


解决这一问题的一个办法,可能是强制 sum 的调用者将较小的类型强制转换(第 5.12.4 节)为希望作为结果使用的类型:

  // ok: now either T or U works as return type
  int i; short s;
  sum(static_cast<int>(s), i); // ok: instantiates int sum(int, int)

★这个办法我就压根就没看明白作者想要表达的意思,我试了下,见下面代码(IDE: VS2010)

C/C++ code
#include <iostream>using namespace std;template <typename T, typename U> U sum( const T& v1, const U& v2 )          //这里我试了下,U或者T作为返回值类型都可以{    return v1 + v2; }int main( void ){    long v3 = sum(3, 4L);    cout<<v3<<endl;    return 1;}

我不明白书里说的这个是什么意思

还有下面这个它说的第二种办法
在返回类型中使用类型形参:
为调用提供显式模板实参与定义类模板的实例很类似,在以逗号分隔、用尖括号括住的列表中指定显式模板实参。显式模板类型的列表出现在函数名之后、实参表之前:
★这里它先是这样写的
  // ok T1 explicitly specified; T2 and T3 inferred from argument types
  long val3 = sum<long>(i, lng); // ok: calls long sum(int, long)
★接着它又换了种写法
  // error: can't infer initial template parameters
  long val3 = alternative_sum<long>(i, lng);
  // ok: All three parameters explicitly specified
  long val2 = alternative_sum<long, int, long>(i, lng);
原因书中描述:
显式模板实参从左至右对应模板形参相匹配,第一个模板实参与第一个模板形参匹配,第二个实参与第二个形参匹配,以此类推。假如可以从函数形参推断,则结尾(最右边)形参的显式模板实参可以省略。如果这样编写 sum 函数:

  // poor design: Users must explicitly specify all three template parameters
  template <class T1, class T2, class T3>
  T3 alternative_sum(T2, T1);

则总是必须为所有三个形参指定实参:
  // error: can't infer initial template parameters
  long val3 = alternative_sum<long>(i, lng);
  // ok: All three parameters explicitly specified
  long val2 = alternative_sum<long, int, long>(i, lng);

我试了下,这样写
C/C++ code
#include <iostream>using namespace std;template <typename T1, typename T2, typename T3> T1 sum( const T2& v1, const T3& v2 ){    return v1 + v2; }int main( void ){    long v3 = sum<long>(3, 4L);            //这里我还是按照原来书中说是错误的方法写的,编译运行一切OK    cout<<v3<<endl;    return 1;}

没啥错误啊,不知道怎么回事,请高人指点!



[解决办法]
template <class T1, class T2, class T3>
T3 alternative_sum(T2, T1);

template <typename T1, typename T2, typename T3> 
T1 sum( const T2& v1, const T3& v2 )

你举的例子和书上表达的不一样,这样试试:
template <typename T1, typename T2, typename T3> 
T3 sum( const T2& v2, const T1& v2 )

这里我最最近也看了,但是没有像你这么认真上级试过。
[解决办法]
类型转换问题。
用强制转换,只是为了确定数据空间的大小,以足够容纳数据。
应该是说,这样并非不对,只是会不安全。
个人觉得C++ Primer不光介绍了语法,还会介绍一些良好的习惯。
具体楼主可以看下下面的代码。
C/C++ code
#include <iostream>using namespace std;template <typename T, typename U> U sum( const T& v1, const U& v2 ){    return v1 + v2; }int main( void ){    char c = 123;    long lng = 456;    long v3 = sum(lng, c);     cout<<v3<<endl;    return 1;} 


[解决办法]
这时候根据显式模板实参,T1是char,然后根据模板实参推断出T2是long,然后T1根据c的类型推断出char,所以T3是什么类型编译器无法得知。然后我试了下T1到底是什么类型,下边的代码似乎说明T1是靠显式模板参数来初始化的
你整体把我看的都有点晕晕的。
-
T1代码中显示初始化是long怎么是char?
T3无法得知类型,是上面代码,还是下面的代码?似乎你的说法都不成立。
-
模板其实你就把类型当成参数看就好了。
没那么复杂。

探讨

引用:

类型转换问题。
用强制转换,只是为了确定数据空间的大小,以足够容纳数据。
应该是说,这样并非不对,只是会不安全。
个人觉得C++ Primer不光介绍了语法,还会介绍一些良好的习惯。
具体楼主可以看下下面的代码。
C/C++ code
#include <iostream>
using namespace std;

template <type……

热点排行