【问题标题】:C++ - Is it possible to instantiate a `vector` without specifying the type?C++ - 是否可以在不指定类型的情况下实例化“向量”?
【发布时间】:2015-10-07 10:44:22
【问题描述】:

如此基本,但我很难在 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&lt;int&gt; v1(10, 0) 时,它会编译,我认为应该是这样的。

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

【问题讨论】:

  • 不,这不可能,你必须指定类型。
  • 不,您不能从构造函数中推断出类模板参数。有一些关于这种功能的提议,但它们引起了很大的争议。
  • 你可以有一个别名来编译上面的代码。(例如 typedef std::vector vector;)但我怀疑这不是你要问的。
  • 你用一个 boost::any 我猜想把它装满,但这几乎不一样......
  • 理论上,您可以通过using vector = std::vector&lt;int&gt;; 定义别名,然后使用vector 而不是std::vector&lt;int&gt;。但它不适用于您的情况,因为它会与using namespace std; 产生歧义。但是你可以说using numbervector = std::vector&lt;int&gt;; 或者你喜欢怎么称呼它。

标签: c++ vector stl


【解决方案1】:

不,std::vector 是模板,不指定模板参数就无法实例化。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 这是课程中的代码示例。由于说 error,我无法编译它。
    【解决方案3】:

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

    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问题和相关问题。

    【讨论】:

    • hmm 很有趣,给定函数 can 推断模板参数,您可以通过对值类型进行模板化来扩展它。比如:template &lt;typename size_type, typename value_type&gt; std::vector&lt;vaule_type&gt; make_vector(size_type size, value_type val) { ... }
    • @PeterSW size_type 不需要(也不应该)是模板参数。
    【解决方案4】:

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

    #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;
    }
    

    注意,谨慎使用“使用”。

    【讨论】:

      【解决方案5】:

      一般模板

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

      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,您必须为该参数指定一个类型。

      【讨论】:

        【解决方案6】:

        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”标志进行编译。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-06-27
          • 1970-01-01
          • 1970-01-01
          • 2020-10-11
          • 2017-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多