繁体   English   中英

c ++编译器如何知道参数是STL容器?

[英]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),则编译器将引发以下错误:

  • 错误C2100:非法间接
  • 错误C2228:“。cbegin”的左侧必须具有class / struct / union
  • 错误C3536:'iElement':在初始化之前无法使用

建议编译器确实了解需要具有一些基本特征的参数类型。

任何人都可以解释一下当列表作为参数发送时,编译器如何“知道”可以使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM