[英]c++ How does compiler know that a parameter is an STL container?
c ++新手问题-C ++编译器如何知道模板函数的参数具有STL方法作为成员? 在C#中,您通常会告诉通用方法参数具有类型约束。 它必须实现一个接口,但是对于c ++模板,参数类型没有限制。
#include <list>
#include <iostream>
using namespace std;
template <typename T>
void DisplayContents (const T& Input)
{
for (auto iElement = Input.cbegin() // no intellisense
; iElement != Input.cend()
; ++ iElement )
cout << *iElement << ' ';
cout << endl;
}
int main ()
{
std::list <int> listIntegers;
listIntegers.push_front (10);
listIntegers.push_front (2011);
listIntegers.push_back (-1);
listIntegers.push_back (9999);
DisplayContents(listIntegers);
// DisplayContents(99); // neither of these will compile
// DisplayContents(new string("")); //
return 0;
}
因此,在模板化方法DisplayContents <>(const T&Input)中,Input上没有智能感知。 键入句点字符时,不会弹出任何建议(这并不令人惊讶,因为function参数尚未指定输入必须是列表或任何其他类型的STL容器)。
但是,如果您尝试将不是STL容器的内容发送到DisplayContents <>(const T&Input),则编译器将引发以下错误:
建议编译器确实了解需要具有一些基本特征的参数类型。
任何人都可以解释一下当列表作为参数发送时,编译器如何“知道”可以使用cbegin()和*运算符,但是当字符串或int发送时(显然不是该类型称为intellisense)时,编译器如何“知道”不使用方法cbegin()吗?
确实很简单。 编译器会假装T
是您传入的参数类型,然后继续进行编译。 如果遇到任何错误,则将报告这些错误。 只要你使用,如果你硬编码的类型会工作参数的类型,那么它会工作。
在您的情况下,由于int没有cbegin()
方法,因此int失败。
由于new std::string("")
失败,因为参数类型变为std::string * const &
,并且您无法在此指针上调用.cbegin()
。 (您必须调用->cbegin()
。)
但是,您可以使用std::string("")
调用它(注意缺少new
),这将导致参数为const std::string &
,并且可以编译。
因此,它与编译器“知道T
代表标准容器”完全无关。 如果你创建一个简单的类型与cbegin()
和cend()
方法,并确保从这些方法的返回值可以增加,废弃时,和平等相比,该类型将工作一样好。
用于制作通用代码的模板。
在这里,编译器将为您生成三个重载函数。
void DisplayContents (const std::list<int>& Input)
void DisplayContents (const int& Input)
void DisplayContents (string* const & Input)
显然版本2和3无法编译,类型const int&
和string* const&
没有方法cbegin()或cend()
PS:由于cdhowie,版本3参数应该为string* const& Input
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.