0

I have a lot of C# Code that I have to write in C++. I don't have much experience in C++.

I am using Visual Studio 2012 to build. The project is an Static Library in C++ (not in C++/CLI).

I am sorry if this has been answered already, but I just couldn't find it.

In the C# code they would initialize a lot of arrays like this:

C#

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

Looking at how they were using arrays, when copying the code to C++ I decided to use std::vector to replace them. I would like to be able to initialize the vectors in the same way, because in the Unit Tests they use the arrays initialisation heavily, but I can't. I think in further versions of c++, vector supports it, but not in the one I have.

(Update)To make my previous statement more clear:

This doesn't work in VS2012:

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

From this question I learned to create a vector from an array, so now I have a function like this:

C++

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

It works great, but now that means I have to create the array and then use my function:

C++ (I would like to avoid this, since the UnitTests have many arrays.)

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

Is there a way I could make my function GetVectorFromArray receive a list of items, that I could later convert into a vector? My compiler doesn't support C++11

Community
  • 1
  • 1
Dzyann
  • 5,062
  • 11
  • 63
  • 95
  • [The link you're mentioning](http://stackoverflow.com/a/12771665/2786682) is gcc-sepecific, but you're using MSVC2012. – Ivan Nov 19 '13 at 14:47
  • Why aren't you using `vector myVector{1, 3, 5}` ? – Johan Nov 19 '13 at 14:48
  • @Johan because it doesn't build. I read that is a newer functionality of vector, i get putting your code: Error 2 error C2143: syntax error : missing ';' before '}' – Dzyann Nov 19 '13 at 14:52
  • @IvanGrynko how dumb I was, I read it and then i completely overlook it. I will edit my question. Bottom line I want to be able to do something like that. – Dzyann Nov 19 '13 at 14:53

3 Answers3

2

You can't have "literal" arrays except when initializing an array in a declaration.

At least that was the case before C++11 standard, which allows things like what you want, but with an std::initializer_list argument:

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

On the other hand, if your compiler support C++11 you can use it directly with the std::vector instead:

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

Or even (with uniform initialization)

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

Note: Unfortunately VS2012 doesn't support these things, so you either to use temporary arrays, or upgrade to a compiler which support it (like VS2013, or GCC, or Clang).


There are alternatives. One of them is the Boost assignment library (as answered by Mark Tolonen).

You can also use old C-style variable arguments. See e.g. this old question and its accepted answer for tips on how to do that. For this to work, you either need to provide the number of elements in the argument list as the first function argument, or provide a special sentinel to mark the end of the list. A warning though: As this is inherited straight from C, the extra type-safety provided by C++ doesn't exist. If you give an argument of the wrong type (say a double or a char) you might get undefined behavior.

The only other solution is to emulate e.g. the Boost assignment library, but that will require ridiculous amounts of code for such a simple thing.

Community
  • 1
  • 1
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I can't use that, but I can not do what I want with any of the previous features of C++? I just need a function that receives something, like variable arguments, and then i create the vector. I read that variable arguments it is not really recommended though. – Dzyann Nov 19 '13 at 14:55
  • @Dzyann You might want to [read this old question](http://stackoverflow.com/questions/1657883/variable-number-of-arguments-in-c), and its accepted answer. However, this requires you to have a sentinel that tells when the list of numbers ends, or a counter saying how many items are in the list as the first argument. – Some programmer dude Nov 19 '13 at 15:06
  • the person answering says that is not safe, is that true? Is the only option I have to implement this in older versions of C++? – Dzyann Nov 19 '13 at 15:11
  • @Dzyann It relies on behavior inherited from C, so it's not type-safe. If you call a function such as that with the wrong kind of argument, it could be the cause of undefined behavior. However, before C++11 that's unfortunately the only way (without using e.g. Boost assign or writing ridiculous amount of code). – Some programmer dude Nov 19 '13 at 15:14
  • thanks. And I assume that the "ridiculous amount of code" would be similar to what boost::assign does? – Dzyann Nov 19 '13 at 15:38
  • if you would answer all this things of the comments in your question, I would mark it as answered. You can leave the C++11 stuff even, because it is a good reference, even if it doesnt work for me XD – Dzyann Nov 19 '13 at 15:45
1

You can simulate this behavior using the third-party C++ library, 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;
}

You can also initialize a vector from an array using only the std library via non-member begin/end:

#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;
}
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
0

Visual studio 2012 does not support initializer list. You could use VS 2013 for support (or g++)

Xale
  • 359
  • 1
  • 5