У меня много кода С#, который я должен написать в C++. У меня нет большого опыта работы в C++.
Я использую Visual Studio 2012 для сборки. Проект представляет собой статическую библиотеку в C++ (не в C++/CLI).
Прошу прощения, если на это уже был дан ответ, но я просто не мог его найти.
В коде С# они инициализируют много массивов, например:
С#
double[] myArray = {10, 20, 30, 40};
Рассматривая, как они используют массивы, при копировании кода на C++ я решил использовать std :: vector для их замены. Я хотел бы иметь возможность инициализировать векторы таким же образом, потому что в Unit Tests они сильно используют инициализацию массивов, но я не могу. Я думаю, что в других версиях C++ вектор поддерживает его, но не в том, что у меня есть.
(Обновление) Чтобы сделать мой предыдущий отчет более ясным:
Это не работает в VS2012:
vector<double> myVector{10, 20, 30, 40};
Из этого вопроса я научился создавать вектор из массива, поэтому теперь у меня есть такая функция:
C++
template<typename T, size_t N>
static std::vector<T> GetVectorFromArray( const T (&array)[N] )
{
return std::vector<T>(array, array+N);
}
Он отлично работает, но теперь это означает, что я должен создать массив, а затем использовать свою функцию:
C++ (я хотел бы избежать этого, так как UnitTests имеет много массивов.)
double array[] = {1, 3, 5};
vector<double> myVector = ArrayUtils::GetVectorFromArray(array);
Есть ли способ, которым я мог бы заставить мою функцию GetVectorFromArray получить список элементов, которые я мог бы позже преобразовать в вектор? Мой компилятор не поддерживает C++ 11
Вы не можете иметь "литерал" массивов, кроме тех случаев, когда инициализация массива в объявлении.
По крайней мере, это было до стандарта C++ 11, что позволяет такие вещи, как вы хотите, но с аргументом 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 };
Или даже (с равномерной инициализацией)
std::vector<int> myVector{ 1, 3, 5 };
Примечание. К сожалению, VS2012 не поддерживает эти вещи, поэтому вы либо используете временные массивы, либо обновляете компилятор, который его поддерживает (например, VS2013, или GCC, или Clang).
Есть альтернативы. Одна из них - библиотека заданий Boost (как ответил Марк Толонен).
Вы также можете использовать старые аргументы переменной стиля C. См., Например, этот старый вопрос и его принятый ответ, чтобы узнать, как это сделать. Для этого вам нужно либо указать количество элементов в списке аргументов в качестве первого аргумента функции, либо предоставить специальный дозор, чтобы пометить конец списка. Предупреждение: поскольку это унаследовано прямо от C, дополнительной безопасности типа, предоставляемой C++, не существует. Если вы дадите аргумент неправильного типа (например, double
или char
), вы можете получить неопределенное поведение.
Единственное другое решение состоит в том, чтобы эмулировать, например, библиотеку присвоения Boost, но для этого потребуются нелепые суммы кода.
Вы можете моделировать это поведение, используя стороннюю библиотеку 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;
}
Вы также можете инициализировать вектор из массива, используя только библиотеку std через 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;
}
Visual Studio 2012 не поддерживает список инициализаторов. Вы можете использовать VS 2013 для поддержки (или g++)
vector<double> myVector{1, 3, 5}
?