c ++ newbie question - 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&lt;&gt;(const T&amp; Input)中,输入上没有智能感知。当您键入句点字符时,不会弹出任何建议(由于函数参数未指定输入必须是列表或任何其他类型的STL容器,因此并不令人惊讶。)
但是,如果您尝试将不是STL容器的内容发送到DisplayContents&lt;&gt;(const T&amp; Input),那么编译器会抛出这些错误: -
建议编译器确实知道需要具有某些基本特征的参数类型。
任何人都可以解释编译器&#34;如何知道&#34;当列表作为参数发送时,可以使用cbegin()和*运算符,但是当发送字符串或int时,可以使用cbegin()和*运算符,当显然类型不被称为intellisense时,不会选择方法cbegin()?
答案 0 :(得分:6)
这很简单,真的。编译器将假装T
是您传入的参数类型,然后继续编译。如果它遇到任何错误,那么它将报告这些错误。只要您使用的参数类型,如果您对该类型进行了硬编码,那么它将工作。
在你的情况下,它因int而没有cbegin()
方法而失败。
它因{1}}而失败,因为参数类型变为new std::string("")
,您无法在此指针上调用std::string * const &
。 (你必须改为调用.cbegin()
。)
但是,你可以用->cbegin()
(注意缺少std::string("")
)来调用它,这将导致参数为new
,这将编译
所以它与编译器没有任何关系&#34;知道const std::string &
代表一个标准容器。&#34;如果使用T
和cbegin()
方法创建一个简单类型,并确保这些方法的返回值可以递增,取消引用并进行相等性比较,那么该类型也可以正常工作。
(模板函数的Here is a demo使用用户定义的类型。)
答案 1 :(得分:0)
用于制作通用代码的模板。
此处编译器将为您生成三个重载函数。
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:版本3 param应为string* const& Input
,感谢cdhowie