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

Почему main() в С++ не перегружен для использования std::string?

Я пытался создать программу, которая принимает аргументы по командной строке, используя аргументы функции main(). Как (основной) программист на С++ (даже если я хорошо знаю указатели и массив в C-стиле), я почти никогда не использовал строки char* и C-массивы. Я потратил несколько, чтобы принять аргументы main() и преобразовать их в std::string... Поэтому задал вопрос: почему в С++ функция main() не перегружена, чтобы взять std::vector<std::string> argv вместо старого char* argv[]?

Для "перегрузки" я подразумеваю сосуществование функций main(), таких как int main() и int main(int argc, char *argv[]), а не перегрузка нормальной функции, выполняемой программистом.

4b9b3361

Ответ 1

Почему это не стандарт? Простой:

Потому что никто этого не предлагал.

Все идет в стандарт С++, потому что кто-то пишет предложение для него, а затем заставляет других людей голосовать на нем и включать его. Если кто-то на самом деле этого не хочет, это не произойдет.

И учитывая, насколько тривиальна эта функция:

int main(int argc, char **argv)
{
    std::vector<std::string> args(argv, argv + argc);
    ...
}

Там просто нет никакой реальной необходимости. Это удобная функция, и она даже не делает того, что удобно по сравнению с альтернативой.

Ответ 2

почему в С++ функция main() не перегружена, чтобы взять std::vector argv вместо старого char * argv []

Потому что это требует зависимости от <string> библиотеки. Философия С++ всегда "не платит за то, что вы не используете". Если кто-то не хочет автоматическое управление памятью, предлагаемое string, тогда они не могут быть принудительно выполнены.
2-й вид: если на какой-либо платформе нет поддержки библиотеки, вы не можете запустить свою С++-программу!

Наоборот, аргументы int и char** являются встроенными и независимыми типами. Всегда можно написать пользовательскую оболочку на main(), которая делает именно то, что вам нужно.

Изменить: комментарий к AProgrammer:
Предположим, что main(vector<string>) разрешено; то, если платформа соответствует всем возможностям С++, но не имеет стандартной поддержки библиотеки, то она станет нестандартной.

Ответ 3

Основная причина, я подозреваю, заключается в том, что обычная реализация сделайте его extern "C" функцией с varargs. Во многих реализаций, это библиотека времени выполнения C, которая вызывает main.

Есть много способов обойти это, но ни один из них не стоит беспокоить, учитывая, насколько легко преобразовать аргументы во все, что вы хотите.

Ответ 4

Было бы тривиально, если компилятор должен скомпилировать основную часть, определенную как

int main(std::vector<std::string> args) {
    ...
}

поскольку он был записан как

int main(int __argc, char **__argv) {
    std::vector<std::string> args(__argv, __argv+__argc);
    ...
}

Было бы даже легко разрешить любой контейнер, даже настраиваемый, а не только std::vector<std::string>. Но это не стандарт, потому что - стандартный ответ на вопрос, почему это не в стандарте - никто не предложил его и убедил достаточно людей, что это хорошая идея. Я не думаю, что было предложение, так что, вероятно, нет оснований для его отказа. Возможно, это изменение просто для большинства вовлеченных людей.

Ответ 5

В принципе, std::vector НЕ совпадает (в макете памяти или чем-либо) в виде массива char *. Чтобы это разрешить, вам нужно заставить компилятор распознать новое основное объявление и добавить обертку в запись, которая создала вектор строк.

Учитывая, что вы делали это, вы могли бы также выбросить argc, а также объявить о главном

int main(std::vector<std::string> argv)

Но он работает для компилятора. Вам нужно было бы получить много людей, которые думали, что это стоит.

В противном случае вы можете просто сделать это самостоятельно

int main(int argc, char **argv)
{
    std::vector<std::string> args;
    args.reserve(argc);
    for (std::size_t arg = 0; arg < argc; ++arg)
    {
         args.push_back(argv[i]);
    }
    return mymain(args);
}

Код не гарантированно скомпилирован или работает, потому что я просто написал его с головы.

или (лучше, благодаря AProgrammer)

int main(int argc, char **argv)
{
    return mymain(std::vector<std::string>(argv, argv + argc));
}