C++ - 是否可以在不指定类型的情况下实例化“vector”?

C++ - Is it possible to instantiate a `vector` without specifying the type?

非常基本,但对我来说很难在 Google 中搜索。

我在网上做一个C++培训课程,主题是STL;在这种情况下 vector.

是否可以在不指定类型的情况下实例化一个vector

#include <vector>
#include <iostream>

using namespace std;

int main()
{
    vector v1(10, 0);
    cout<<"Size: "<<v1.size()<<endl;
    for(unsigned i = 0; i < v1.size(); ++i)
    {
        cout<< v1[i]<<" ";
    }
    cout<<endl;
    return 0;
}

我认为这是错误的,但我在整个课程中都看到了这一点,这让我很困惑。

当使用vector<int> v1(10, 0)然后它编译,这就是我认为的方式。

在课程中我们使用的是 NetBeans,但我认为没有配置或参数或任何可以实现这一点的东西,是吗?

不行,std::vector是一个模板,不指定模板参数就不能实例化。

除了语法错误之外,没有类型的向量在逻辑上毫无意义。您要的是一份清单,但什么也没有……您究竟希望它打印出什么?

您必须指定类型,因为它不是从构造函数的参数中推断出来的。但是,没有人禁止你这样做

std::vector<int> make_vector(std::vector<int>::size_type n, int val)
{
      return std::vector<int>(n, val);
}

// ...
auto v2 = make_vector(10, 0);

为什么这是不可能的,请查看this问题和相关问题。

有可能(使用不同的设置):

#include <vector>
#include <iostream>

using std::cout;
using std::endl;
using vector = std::vector<int>;

int main()
{
    vector v1(10, 0);
    cout<<"Size: "<<v1.size()<<endl;
    for(unsigned i = 0; i < v1.size(); ++i)
    {
        cout<< v1[i]<<" ";
    }
    cout<<endl;
    return 0;
}

注意,谨慎使用'using'。

通用模板

暂时忽略 std::vector 的细节, 可以为 class 模板的模板参数定义默认类型。例如:

template <class T = int>
class foo { 
    T *bar;
};

在这种情况下,您 没有 指定类型来实例化该模板。同时,您 必须包含一个模板参数列表。诀窍在于列表可以为空,因此您可以通过以下任何一种方式实例化此模板:

foo<long> a; // instantiate over long. The `int` default is just ignored
foo<int>  b; // instantiate over int. Still doesn't use default
foo<>     c; // also instantiates over int

std::vector 具体来说

std::vector 确实使用了分配器类型的默认参数,但没有为存储的类型提供默认参数,因此定义看起来像这样:

template <class T, class allocator = std::allocator<T>>
class vector
// ...

因此,如果您没有另外指定,向量的分配器类型将是 std::allocator 实例化在与您存储相同的类型上——但您 总是必须指定要存储的类型,因为没有为该类型提供默认值。

总结

绝对可以为模板的所有参数指定默认值,在这种情况下,可以实例化模板而无需(明确地)在实例化时指定类型——但是 std::vector 只有一个模板未提供默认值的参数,因此要实例化 vector,您必须为该参数指定类型。

C++17 确实支持没有类型的向量实例化。请看这篇文章,https://en.cppreference.com/w/cpp/language/class_template_argument_deduction

了解更多信息。

所以,例如写这个会起作用:

vector v {1, 2, 3};  // instead of vector<int>

如果你用这个“-std=c++17”标志编译。