Почему я не могу передать строковый литерал в этот шаблон? - PullRequest
1 голос
/ 28 сентября 2019

Вот шаблон

template <int LEN_1, int LEN_2>
bool less (char const (*arr1)[LEN_1], char const (*arr2)[LEN_2]) {
    for (int i=0; i<LEN_1 && i<LEN_2; ++i) {
        if (arr1[i]<arr2[i]) return true;
        if (arr1[i]>arr2[i]) return false;
    }
    return LEN_1 < LEN_2;
}

Я пытаюсь передать строковый литерал в качестве аргументов от main, например:

std::string a = "hello";
std::string b = "ok";

::less(a, b);

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

Пожалуйста, сделайте мне одолжение разбить это яйцо.

1 Ответ

2 голосов
/ 28 сентября 2019

Это не разрешено C ++.Если вы хотите, чтобы массивы разрушались, вы должны передать размер явно.Вот синтаксис для него:

bool less (char const *arr1, std::size_t LEN_1, char const *arr2, std::size_t LEN_2) {
    for (std::size_t i=0; i<LEN_1 && i<LEN_2; ++i) {
        if (arr1[i]<arr2[i]) return true;
        if (arr1[i]>arr2[i]) return false;
    }
    return LEN_1 < LEN_2;
}

Но вы, похоже, хотите передать массив по ссылке.Вот как вы это делаете:

template <std::size_t LEN_1, std::size_t LEN_2>
bool less (char const (&arr1)[LEN_1], char const (&arr2)[LEN_2]) {
    for (std::size_t i=0; i<LEN_1 && i<LEN_2; ++i) {
        if (arr1[i]<arr2[i]) return true;
        if (arr1[i]>arr2[i]) return false;
    }
    return LEN_1 < LEN_2;
}

Обратите внимание на использование std::size_t вместо int.

В качестве альтернативы вы можете использовать нулевой терминатор вместо размера:

bool less (char const arr1[], char const arr2[]) {
    for (/*nothing*/;*arr1 && *arr2; ++arr1, ++arr2) {
        if (*arr1 < *arr2) return true;
        if (*arr1 > *arr2) return false;
    }
    return !*arr1;
}

Однако в вашем примере вы передаете экземпляры std::string, а не массивы символов.В этом случае вам не нужна пользовательская функция.Перегруженный operator< делает то, что вы хотите.Если вы действительно хотите использовать свою функцию, используйте std::string::c_str:

less(a.c_str(), b.c_str());

Или вы можете передать литералы напрямую:

less("hello", "ok");
...