使用此类型函数有什么优势
What is the advantage of using this Type Function?
>在"C++ Templats Complete Guide 2nd Edition"一书"19.3 Type Functions"一节中,它提出了以下问题:
假设我们有许多容器模板,例如 std::vector<> 和 std::list<>,以及内置数组。我们想要一个 类型函数,给定这样的容器类型,生成元素 类型。这可以通过部分专业化来实现。
然后提供以下答案:
#include <vector>
#include <list>
#include <iostream>
#include <typeinfo>
template<typename T>
struct ElementT;
template<typename T>
struct ElementT<std::vector<T>>
{
using Type = T;
};
template<typename T>
struct ElementT<std::list<T>>
{
using Type = T;
};
template<typename T, std::size_t N>
struct ElementT<T[N]>
{
using Type = T;
};
template<typename T>
struct ElementT<T[]>
{
using Type = T;
};
template<typename T>
void printElementType(T const& c)
{
std::cout << "Container of "
<< typeid(typename ElementT<T>::Type).name()
<< " elementsn";
}
int main()
{
std::vector<int> intVec = {1, 2, 3};
std::list<double> doubleList = {1.1, 2.2, 3.3};
bool boolArr[] = {false, false, true, false, true};
//GNU COMPILER:
printElementType(intVec); //Container of i elements
printElementType(doubleList); //Container of d elements
printElementType(boolArr); //Container of b elements
}
我的问题是,当我们可以编写像波纹管这样的简单函数时,这种方法的优势是什么?
#include <iostream>
#include <typeinfo>
#include <vector>
#include <list>
template<typename T>
void printType(const T& container)
{
std::cout << "Container of "
<< typeid(T).name()
<< " elementsn";
}
int main()
{
std::vector<int> intVec = {1, 2, 3};
std::list<double> doubleList = {1.1, 2.2, 3.3};
bool boolArr[] = {false, false, true, false, true};
//GNU COMPILER:
printType(intVec); //Container of St6vectorIiSaIiEE elements
printType(doubleList); //Container of St4listIdSaIdEE elements
printType(boolArr); //Container of A5_b elements
}
还有第二个问题:为什么结果不同?这些额外信息是什么?
谢谢。
2 个主要区别:
-
书籍版本获取容器中元素的类型,而您的版本仅打印容器的类型。此外,您的版本接受任何类型,即使它不是容器。例如,在书的版本中,类型是
int
,而在您的版本中是std::vector<int>
。 -
书籍版本"获取"类型。这可以进一步用于定义其他类型。您的版本将打印信息。除了打印它,您不能做任何其他事情。不能使用它来组合其他类型或声明变量。
这就像两者之间的区别:
int max(int a, int b) { if (a > b) return a ; else return b; }
和
void print_max(int a, int b) { if (a > b) std::cout << a << 'n'; else std::cout << b << 'n'; }
第一个功能远远优于第二个功能。您可以使用它来执行仅打印最大值的其他操作。例如:
int max(int a, int b, int c) { return max(a, max(b, c)); }
您可以对图书版本执行哪些操作的示例,但不能使用您的版本:
template <class Container> typename ElementT<Container>::Type foo(const Container& cont) { typename ElementT<Container>::Type sum = 0; for (const auto& e : cont) { sum += e; } return sum; }
相关文章:
- 什么时候调用组成单元对象的析构函数
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 什么时候调用析构函数
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 是什么让放置新调用对象的构造函数?
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 在C 中,对2D数组的增量是什么?函数断言(0)做什么?
- 我应该使用什么函数签名来返回对可能不存在的对象的引用
- 一个类的构造函数,为另一个类进行强制转换.将调用什么函数
- 在 opencv for c 中,什么函数与 Mat::convertTo 和 cvtColor() 完全相同
- 当按下Alt-Enter键时调用什么函数
- C库导出什么函数?
- 使用什么函数来选择文本
- c++在空类中编写和调用什么函数?
- 在共享库的构造函数(_init部分)中,如何知道什么函数被中断了?
- 我可以用什么函数来获取按钮的把手