最近读C++ template 一书,在读的过程中使用Visual Studio 2015,发现很多时候与书中描述的结果大相径庭,在此记录一些槽点,VS确实很多时候与标准有较大的出入。
1. 书中提到:函数模板重载的时候,不同的重载形式之间最好只存在【绝对必要的差异】,确保所有形式的重载函数都要被卸载它们的被调用点之前
比如下面这段代码,按照书中的描述,三个参数的max函数版本会调用模板函数max,而不是重载的非模板函数max,因为在它之前只有模板的版本可用。(一般来说重载的时候非模板的优先级会高于模板函数,当两个函数都完全匹配目标调用的时候会先使用非模板的版本)
inline T const& max (T const& a, T const& b)
{
return a < b ? b : a;
}
// 传回三个任意类型值的最大者
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
return ::max (::max(a,b), c);
// 即使自变量类型都是 int,这里也会调用 max()template。因为下面的函数定义来得太迟。
}
// 传回两个 ints 的较大者
inline int const& max (int const& a, int const& b)
{
return a < b ? b : a;
}但是我在VS2015测试的结果却与上述描述不同:
#include <iostream>
template <typename T>
inline T const& max(T const& a, T const& b)
{
std::cout << "calling template max" << std::endl;
return a < b ? b : a;
}
template <typename T>
inline T const& max(T const& a, T const& b, T const& c)
{
return ::max(::max(a, b), c);
}
inline int const& max(int const& a, int const& b)
{
std::cout << "calling non-template max" << std::endl;
return a < b ? b : a;
}
int main()
{
::max(1, 2, 3);
}输出的结果如下:
之后在g++上同样进行测试,输出结果如下:
和书中描述的一致。
2. 书中提到的另一个问题 是 “绑定到临时对象的引用”,描述如下:
#include <iostream>
template <typename T1, typename T2>
inline T1 const& max(T1 const& a, T2 const& b)
{
return a < b ? b : a;
}
int main()
{
max(3, 3.2);
}当函数使用返回值类型是引用类型的时候,由于函数会出现类型转换(导致出现临时的变量),使得返回值会绑定到一个临时的变量。书中提到会出现错误,但目前测试在VS和g++中都只是给出警告。
本文通过实际测试案例,对比了Visual Studio 2015与C++模板函数重载、绑定到临时对象的引用之间的表现差异,揭示了两者在实现细节上的不一致性。
922

被折叠的 条评论
为什么被折叠?



