Как поменять две строки в стиле C, используя ссылки C ++?

Приведенный ниже код дает мне ошибку компиляции, но я не понимаю, что я делаю неправильно. Извините, что задаю такой глупый вопрос.

$ 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*&)’
$

1

Решение

Массивы не могут быть изменены, и они просто распад к временным указателям, они на самом деле не являются указателями и не могут быть обменены. Адрес массива не может быть изменен, и компилятор выдает ошибку, когда вы пытаетесь связать временный указатель, полученный из массива, с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";
8

Другие решения

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]);
}

Этот шаблон гарантирует, что оба аргумента являются массивами одинаковой длины.

3

По вопросам рекламы [email protected]