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”标志编译。
非常基本,但对我来说很难在 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”标志编译。