Приведенный ниже код дает мне ошибку компиляции, но я не понимаю, что я делаю неправильно. Извините, что задаю такой глупый вопрос.
$ cat swapcstrings.cc
#include <iostream>
void swap(char*& c, char*& d) {
char* temp = c;
c = d;
d = temp;
}
int main() {
char c[] = "abcdef";
char d[] = "ghijkl";
std::cout << "[" << c << "," << d << "]\n";
swap(c, d);
std::cout << "[" << c << "," << d << "]\n";
}
$ g++ swapcstrings.cc
swapcstrings.cc: In function ‘int main()’:
swapcstrings.cc:13: error: invalid initialization of non-const reference of type ‘char*&’ from a temporary of type ‘char*’
swapcstrings.cc:3: error: in passing argument 1 of ‘void swap(char*&, char*&)’
$
Массивы не могут быть изменены, и они просто распад к временным указателям, они на самом деле не являются указателями и не могут быть обменены. Адрес массива не может быть изменен, и компилятор выдает ошибку, когда вы пытаетесь связать временный указатель, полученный из массива, сconst
ссылка, которая противоречит правилам языка.
Объявите массивы, затем поменяйте местами два указатели им.
char a[] = "abcdef";
char b[] = "defghi";
char* aptr = a, *bptr = b;
std::cout << "[" << aptr << "," << bptr << "]\n";
swap(aptr, bptr);
std::cout << "[" << aptr << "," << bptr << "]\n";
Или, если вы можете изменить прототип функции, используйте const char*
на первом месте:
void swap(const char*& c, const char*& d) {
const char* temp = c;
c = d;
d = temp;
}
const char* c = "abcdef", // These must be const char* because the arrays are
* d = "ghijkl"; // const char[N]
std::cout << "[" << c << "," << d << "]\n";
swap(c, d);
std::cout << "[" << c << "," << d << "]\n";
c
а также d
являются массивами. Они будут автоматически преобразованы в указатели, где указатели требуются. Это «временный» вывод вашего компилятора. Думайте об этом так:
char c[] = "abcdef", d[] = "ghijkl";
char *cp = (char*)c, *dp = (char*)d;
swap(cp, dp);
Выше скомпилируется, но только подкачка cp
а также dp
не оригинал c
а также d
, Поскольку приведенный выше код дает имена этим указателям, теперь вы можете иметь ссылки и на них. Но в вашем исходном коде временные имена не имели имен, и любая их модификация была бы признаком вероятной ошибки. Таким образом, компилятор не позволит вам сделать это, и вместо этого будет жаловаться.
Если вы хотите обмениваться строками в стиле C в своих массивах, вам придется делать это по одному символу за раз:
template<size_t n> void swap(char (&a)[n], char (&b)[n]) {
for (size_t i = 0; i != n; ++i)
std::swap(a[i], b[i]);
}
Этот шаблон гарантирует, что оба аргумента являются массивами одинаковой длины.