Массив инициализации тела как параметр функции (C-массив), возможно ли это?
Я ищу помощь в следующей ситуации:
У меня есть некоторый класс и некоторый метод, синтаксис выглядит так:
class SomeClass {
public:
void doSomething(int *a);
};
Итак, я хочу вызвать этот метод, например
SomeClass::doSomething({ 0, 1, 2, 3, 4 });
Возможно ли это на любом языке?
Любая (С++, C, obj-c, obj-С++) реализация приветствуется!
Я знаю, что этот блок инициализации является массивом массива, например
int *a = { 0, 1, 2, 3, 4 };
SomeClass::doSomething(a);
Но интерфейс будет выглядеть великолепно, я думаю, если до вызовов функций не будет переменных temp (так как нам не нужно знать тип параметра в class-client). Итак, есть ли шанс сделать это?
Ответы
Ответ 1
Ниже приведен список инициализаторов С++ 11 (раздел 18.9).
void foo (std :: initializer_list <int> inputs) {
for (auto i : inputs) {
// ...
}
}
foo ({10, 20, 30});
Только компилятор может создать список инициализаторов, но вы можете рассматривать его как стандартный контейнер в стиле STL с begin()
, end()
, size()
и итераторами с произвольным доступом.
std::vector
(и я ожидаю, что некоторые другие контейнеры) теперь можно построить с помощью списков инициализаторов, поэтому
std :: vector <std :: string> foo {"a", "b"};
эквивалентно
std :: vector <std :: string> foo;
foo .push_back ("a");
foo .push_back ("b");
за исключением того, что он может выполнять меньше распределений. Обратите внимание, что const char*
автоматически преобразуется в std::string
.
Ответ 2
В C99 это работает:
functionThatTakesIntPtrOrArray( (int []){ 1, 2, 3, 4 } );
.. и подобные вещи могут быть сделаны с помощью структур.
Ответ 3
Если initializer_list
недоступен, а массивы в основном невелики, есть еще одна опция, перегружая оператор <<
для std::vector следующим образом:
template <typename T>
inline std::vector<T> operator <<( const std::vector<T>& vec, const T& val ) {
std::vector<T> result(vec);
result.push_back(val);
return result;
}
С этим вы можете сделать это:
void foo (const std::vector<int>& inputs) {
// ...
}
foo ( std::vector<int>() << 10 << 20 << 30 );
Существует плата за это удобство однострочной инициализации и отсутствие необходимости указывать размер вектора. Копия предыдущего вектора создается для каждого добавленного элемента, делая время работы не менее квадратичным по размеру вектора - поэтому это лучше всего подходит для коротких векторов и случаев, когда производительность не имеет значения. Существует лучшее решение для С++ 11, как указано в ответе spraff.