Подтвердить что ты не робот

Массив инициализации тела как параметр функции (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). Итак, есть ли шанс сделать это?

4b9b3361

Ответ 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.