【问题标题】:Creating std::vector from list of arguments using Templates使用模板从参数列表创建 std::vector
【发布时间】:2013-12-03 04:20:55
【问题描述】:

我有很多必须用 C++ 编写的 C# 代码。我在 C++ 方面没有太多经验。

我正在使用 Visual Studio 2012 进行构建。该项目是C++ 中的静态库(不是 C++/CLI)。

如果这个问题已经回答了,我很抱歉,但是我找不到它。

在 C# 代码中,他们会像这样初始化很多数组:

C#

double[] myArray = {10, 20, 30, 40};

看看他们如何使用数组,在将代码复制到 C++ 时,我决定使用 std::vector 来替换它们。我希望能够以相同的方式初始化向量,因为在单元测试中他们大量使用数组初始化,但我不能。我认为在 c++ 的其他版本中,vector 支持它,但在我拥有的版本中不支持。

更新)为了让我之前的声明更清楚:

这在 VS2012 中不起作用:

vector<double> myVector{10, 20, 30, 40};

this question我学会了从数组中创建一个向量,所以现在我有了这样一个函数:

C++

template<typename T, size_t N>
static std::vector<T> GetVectorFromArray( const T (&array)[N] )
{
    return std::vector<T>(array, array+N);
}

效果很好,但现在这意味着我必须创建数组然后使用我的函数:

C++(我想避免这种情况,因为 UnitTest 有很多数组。)

double array[] = {1, 3, 5};
vector<double> myVector = ArrayUtils::GetVectorFromArray(array);

有没有办法让我的函数 GetVectorFromArray 接收项目列表,然后我可以将其转换为向量? 我的编译器不支持 C++11

【问题讨论】:

  • The link you're mentioning 是 gcc 专用的,但您使用的是 MSVC2012。
  • 你为什么不用vector&lt;double&gt; myVector{1, 3, 5}
  • @Johan 因为它没有构建。我读到这是矢量的更新功能,我得到了你的代码:错误 2 错误 C2143:语法错误:缺少';'在'}'之前
  • @IvanGrynko 我是多么愚蠢,我读了它然后我完全忽略了它。我将编辑我的问题。底线我希望能够做这样的事情。

标签: c++ arrays vector


【解决方案1】:

Visual Studio 2012 不支持initializer list。您可以使用 VS 2013 来获得支持(或 g++)

【讨论】:

    【解决方案2】:

    除非在声明中初始化数组,否则不能有“文字”数组。

    至少在C++11 standard 之前是这样的,它允许你想要的东西,但带有std::initializer_list 参数:

    template<typename T>
    static std::vector<T> GetVectorFromArray( std::initializer_list<T> list )
    {
        return std::vector<T>(list);
    }
    

    另一方面,如果您的编译器支持 C++11,您可以直接将其与 std::vector 一起使用:

    std::vector<int> myVector = { 1, 3, 5 };
    

    甚至(使用uniform initialization

    std::vector<int> myVector{ 1, 3, 5 };
    

    注意:不幸的是 VS2012 不支持这些东西,所以您要么使用临时数组,要么升级到支持它的编译器(如 VS2013、GCC 或 Clang)。 p>


    还有其他选择。其中之一是 Boost 分配库(Mark Tolonen 的 answered)。

    您也可以使用旧的 C 风格的变量参数。参见例如this old question 及其 accepted answer 获取有关如何执行此操作的提示。为此,您需要提供参数列表中元素的数量作为第一个函数参数,或者提供一个特殊的标记来标记列表的结尾。但是有一个警告:由于这是直接从 C 继承的,因此 C++ 提供的额外类型安全性不存在。如果您提供错误类型的参数(例如 doublechar),您可能会得到未定义的行为。

    唯一的其他解决方案是模仿例如Boost 赋值库,但是对于这样一个简单的事情需要大量的代码。

    【讨论】:

    • 我不能使用它,但是我不能用 C++ 以前的任何功能做我想做的事?我只需要一个接收一些东西的函数,比如变量参数,然后我创建向量。我读到了变量参数,但实际上并不推荐它。
    • @Dzyann 你可能想read this old question,以及它接受的答案。但是,这需要您有一个哨兵来告知数字列表何时结束,或者有一个计数器来说明列表中有多少项目作为第一个参数。
    • 回答的人说不安全,是真的吗?是我必须在旧版本的 C++ 中实现这一点的唯一选择吗?
    • @Dzyann 它依赖于从 C 继承的行为,因此它不是类型安全的。如果您使用错误类型的参数调用诸如此类的函数,则可能是未定义行为的原因。然而,不幸的是,在 C++11 之前这是唯一的方法(不使用例如 Boost 分配或编写荒谬的代码)。
    • 谢谢。而且我认为“可笑的代码量”类似于 boost::assign 所做的?
    【解决方案3】:

    您可以使用第三方 C++ 库Boost 模拟此行为:

    #include <boost/assign.hpp>
    #include <vector>
    #include <iostream>
    
    int main()
    {
        std::vector<int> v = boost::assign::list_of(1)(2)(3)(4)(5);
        for(auto i : v)
            std::cout << i << std::endl;
    }
    

    您还可以通过非成员开始/结束仅使用标准库从数组初始化向量:

    #include <boost/assign.hpp>
    #include <vector>
    #include <iostream>
    
    int main()
    {
        int array[] = {1,2,3,4,5,6,7,8,9,10};
        std::vector<int> v(std::begin(array),std::end(array));
        for(auto i : v)
            std::cout << i << std::endl;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 2019-09-07
      • 2013-05-31
      • 2021-08-13
      相关资源
      最近更新 更多