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

标签 c++ templates intellisense

C++ 新手问题 - C++ 编译器如何知道模板函数的参数具有 STL 方法作为成员?在 C# 中,您通常会告诉泛型方法参数具有类型约束。它必须实现一个接口(interface),但使用 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) 中,输入没有智能感知。当您键入句点字符时,不会弹出任何建议(这并不奇怪,因为函数参数未指定输入必须是列表或任何其他类型的 STL 容器)。

但是,如果您尝试将不是 STL 容器的内容发送到 DisplayContents<>(const T& Input),则编译器会抛出以下错误:-

  • 错误 C2100:非法间接寻址
  • 错误 C2228:'.cbegin' 的左边必须有类/结构/union
  • error C3536: 'iElement': 在初始化之前无法使用

表明编译器确实知道需要具有一些基本特征的参数类型。

谁能解释一下编译器如何“知道”当列表作为参数发送时可以使用 cbegin() 和 * 运算符,而不是当发送字符串或 int 时,显然类型不是被称为 intellisense 的方法没有采用 cbegin() 方法?

最佳答案

其实很简单。编译器会假设 T 是您传入的参数类型,然后继续编译。如果它遇到任何错误,那么它会报告这些错误。只要您使用的参数类型有效,如果您对该类型进行硬编码,那么它就会有效。

在您的情况下,它因 int 而失败,因为 int 没有 cbegin() 方法。

它以 new std::string("") 失败,因为参数类型变成了 std::string * const &,你不能调用 .cbegin() 在这个指针上。 (您必须改为调用 ->cbegin()。)

但是,您可以使用 std::string("") 调用它(注意缺少 new),这将导致参数为 const std::string &,这将编译。

因此它与编译器“知道 T 表示标准容器”完全无关。如果您使用 cbegin()cend() 方法创建一个简单类型,并确保这些方法的返回值可以递增、取消引用和比较是否相等,这种类型也可以。

(使用用户定义类型的模板函数的 Here is a demo。)

关于c++编译器如何知道参数是STL容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26717837/

相关文章:

c# - 如何将结构从 C# 传递到 C++ DLL?

c++ - 带有 boost::fast_pool_allocator 的模板模板参数

visual-studio-2010 - Visual Studio 2010 XAML 编辑器笨拙的 IntelliSense?

c++ - 查找数组的最小子序列

c++ - QGraphicsPixmapItem如何设置鼠标碰撞框? [QT/C++]

c++ - Perl 捕获嵌入式脚本的标准输出,如果在 dlopen 加载的共享库中则失败

c# - GraphQL .NET Core Visual Studio 2019 错误建议

C++17 模板推导指南不用于空参数集?

c++ - 使用基于模板的构造函数构造 std::function

android - 原生Android VS2015无法打开源文件