Почему я не могу сделать foo({"asd","asd1"}) с foo(char* args[])?
Я читаю C++ Primer и в разделе 6.2 он говорит:
"инициализация параметров работает так же, как и переменная инициализация."
но когда я это делаю:
void foo(char* args[]) {return;}
int main() {
char* args[]={"asd","dsa"}; // ok.
foo({"asd","dsa"}); // error.
}
почему это?
4 ответов
Как @ T. C. указал в комментариях, args в аргументе функции преобразуется в char**, потому что функции не могут принимать массивы в качестве аргумента. Так как вы не можете сделать
char **asd={"asd","dsa"};
кодекса является незаконным. Мое смущение было вызвано тем, что
char* args[]={"asd","dsa"};
char **asd=args;
является законным.
обычно можно воспользоваться новым синтаксисом инициализации и семантикой для использования анонимных массивов в качестве аргументов, но вам придется прыгать через несколько обручей. Например
typedef const char *CC2[2];
void foo(const CC2 &a) {}
int main() {
foo({ "asd", "dsa" });
}
однако в вашем случае этот метод не поможет, потому что вы запрашиваете преобразование массива в указатель на временный массив. Это незаконно на C++.
typedef int A[2];
const A &r = A{ 1, 2 }; // reference binding is OK
int *p = A{ 1, 2 }; // ERROR: taking address is not OK
поэтому, если вы действительно хотите сделать что-то подобное, вы можете сделать после
template <size_t N> void foo(const char *const (&args)[N]) {}
int main() {
foo({ "asd", "dsa" });
}
но это не совсем то, что вы изначально в виду.
"инициализация параметров работает так же, как и инициализация переменных."
Это касается как строителей, я думаю, они имеют в виду. Однако инициализаторы являются специальными и отличаются от обычных выражений значений, которые можно назначить переменной или передать вызову функции.
C / C++ не имеет способа написать литеральный анонимный массив. Вы можете сделать это только как инициализатор при объявлении переменной.
почему это?
прежде всего в обоих случаях вам нужно char const*
потому что вы работаете со строковыми литералами.
во-вторых, {...}
может работать, если тип параметра является массивом, но char*[]
is скорректированная to char**
(из-за decayment), который не может быть инициализирован с braced-init-list.
можно использовать std::string
и std::vector
, а вы уже должны do:
void foo(std::vector<std::string> args) {return;}
и:
foo({"asd","dsa"});
будет работать нормально.