C++ string() сравнение с c-строкой. ПОЧЕМУ ЭТО РАБОТАЕТ?

Таким образом, этот код предназначен для ввода команды в любом случайном порядке, и он вернет значение, которое приходит после вашего ввода. Amt_Range — это функция проверки цифр.

Почему это работает? Это должно быть в состоянии из-за сравнения указателя.??

Что еще более важно, что делает string(). По моему ограниченному пониманию, сравнение не должно работать, потому что строка стиля c имеет форму '-' 't'. Заранее спасибо!!

int main(int argc, const char *argv[]) {

string dummy;
int tests = 0, quizzes = 0, assignments = 0, labs = 0, fin = 0;
int testweight = 0, quizweight = 0, assignweight = 0, labweight = 0, finweight = 0;
int counter = 1;

    if (argv[counter] == string("-t")) {
        dummy = argv[counter + 1];
        tests = Amt_Range(dummy, "tests");
        counter+=2;

    } else if (argv[counter] == string("-q")) {
        dummy = argv[counter + 1];
        quizzes = Amt_Range(dummy, "quizzes");
        counter+=2;


    } else if (argv[counter] == string("-a")) {
        dummy = argv[counter + 1];
        assignments = Amt_Range(dummy, "assignments");
        counter+=2;


    } else if (argv[counter] == string("-l")) {
        dummy = argv[counter + 1];
        labs = Amt_Range(dummy, "labs");
        counter+=2;


    } else if (argv[counter] == string("-f")) {
        dummy = argv[counter + 1];
        fin = Amt_Range(dummy, "whether there is a final");
        counter+=2;

    } else {
    cout << "wrong input NOW START OVER" << endl;
    exit(EXIT_FAILURE);

    }
}

person DisplayName    schedule 19.11.2014    source источник
comment
К счастью, он не сравнивает указатели (потому что он никогда не сравнивает равные). Кроме того, строки c не имеют формы '-' 't'. Строки C имеют формат char const* или char(&)[N].   -  person sehe    schedule 20.11.2014


Ответы (2)


Перегрузка operator==(), которая срабатывает, является свободной функцией в пространстве имен std.

namespace std { 
     bool operator==(std::string const&, std::string const&);
}

Он принимает первый аргумент const&, что означает, что приветствуется временное.

Временное можно создать с помощью неявного конструктора преобразования std::string(char const*). Таким образом, применяется перегрузка.

ОБНОВЛЕНИЕ Как показано в комментариях, стандарт фактически объявляет

      bool operator==(const char*, std::string const&);

в качестве оптимизации в §21.4.8.2 operator== . Тем не менее полезно знать о неявном преобразовании в LHS, поскольку оно является ключевым элементом конструкции языка в отношении перегрузки операторов (разрешения).


Теперь причина, по которой перегрузка bool std::operator==(std::string const&, std::string const&) обнаруживается даже во время разрешения перегрузки, немного неуловима. Этот механизм известен как поиск, зависящий от аргумента.

В этом случае ADL работает, потому что второй аргумент уже является std::string, тип которого объявлен в пространстве имен std. Следовательно, это пространство имен ищет operator== кандидатов на перегрузку.


ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ:

Я упростил вышесказанное. На самом деле код в стандартной библиотеке еще более общий и, вероятно, больше похож на

namespace std { 
     template <typename Char, typename CharTraits, typename Alloc>
     bool operator==(std::basic_string<Char, CharTraits, Alloc> const&, std::basic_string<Char, CharTraits, Alloc>  const&) {
          // implementation...
     }
}
person sehe    schedule 19.11.2014
comment
Вы имели в виду std::operator==(char const *, std::string const&)? - person vsoftco; 20.11.2014
comment
@ О, я вижу, неважно, он неявно преобразует char const* в std::string через ctor std::string ... - person vsoftco; 20.11.2014
comment
@vsoftco Ты понял! (Кстати, это может быть не самым эффективным решением, поэтому полезно знать об этом. Современные библиотеки С++, как правило, предпочитают конструкторы преобразования explicit по этой причине - и некоторые другие подводные камни, не связанные с этим) - person sehe; 20.11.2014
comment
@Deduplicator, согласен, сначала я думал, что перегрузки существуют, но теперь их нет. - person vsoftco; 20.11.2014
comment
М-м-м. Позвольте мне проверить, что их на самом деле не существует :) Я мог просто не помнить - person sehe; 20.11.2014
comment
@sehe, кажется, они действительно существуют, en.cppreference.com/w/cpp /string/basic_string/operator_cmp Было бы немного странно не сделать этого из-за проблем с производительностью, как упоминал Deduplicator. - person vsoftco; 20.11.2014
comment
Хорошо. Я обновил свой ответ, чтобы он был более точным в этом конкретном случае, хотя я сохранил свое более широкое объяснение, включающее неявные преобразования операнда LHS, потому что я думаю, что это поможет понять тех, кто изучает С++. - person sehe; 20.11.2014
comment
Должен сказать, что я немного смущен ADL. Почему АДЛ здесь? Кажется, у ОП уже есть using namespace std;, поэтому он не звонит operator==(const char*, std::string). Извините за длинную строку комментариев, хотелось бы понять, что вы имели в виду, говоря, что ADL пинает здесь. - person vsoftco; 20.11.2014
comment
@vsoftco У меня есть слепое пятно для using namespace std. Его не следует использовать, поэтому я предполагаю, что он не используется. В реальной жизни код качества производства, ADL, должен помочь. (Так же, как и в std::cout << "hello world\n"; в этом отношении) - person sehe; 20.11.2014
comment
ОК :) +1, в любом случае отличный ответ! - person vsoftco; 20.11.2014
comment
Я не уверен, что разумно называть любую стандартную библиотечную функцию оптимизацией. - person Lightness Races in Orbit; 20.11.2014
comment
@LightnessRacesinOrbit согласился. Я задумался. Хотя как бы вы это назвали? - person sehe; 20.11.2014
comment
--- Вероятно, что-то вроде полезности или удобства. Я не знаю, что-то в этом роде. На самом деле, я думаю, они не совсем подходят; Я только что понял, почему вы крутите маршрут оптимизации. Не уверен, что смогу придумать что-то лучше. - person Lightness Races in Orbit; 20.11.2014

Цитата из стандарта (С++ 14):

21.3 Классы строк [string.classes]

template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs,
    const basic_string<charT,traits,Allocator>& rhs) noexcept;
template<class charT, class traits, class Allocator>
bool operator==(const charT* lhs, const basic_string<charT,traits,Allocator>& rhs);
template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs);

[... то же самое для != < > <= >=]

Или посмотрите в этом разделе:

21.4.8.2 operator== [string::operator==]

Таким образом, есть точное совпадение, которое находится в пространстве имен std (используется ADL (поиск в зависимости от аргументов, подсчет пространств имен аргументов как связанных пространств имен и их поиск), если бы в области действия не было директивы использования).

Кстати: я немного разочарован тем, что два std::basic_string, различающихся только типом распределителя, нельзя сравнивать (аргументы шаблона должны точно совпадать)...
Быстрая демонстрация на coliru: http://coliru.stacked-crooked.com/a/01788a718178c6d2

person Deduplicator    schedule 19.11.2014
comment
Строки, размещенные по-разному, можно сравнивать, если они имеют неявные преобразования. Я знаю, что раньше сравнивал разнородные строки в разделяемой памяти и в других местах. Позвольте мне посмотреть, как это на самом деле сработало (если я все еще могу это найти) - person sehe; 20.11.2014
comment
Должны ли шаблонные аргументы точно не совпадать? - person Deduplicator; 20.11.2014
comment
Буду искать механику. Но вы знаете то, что знаете, и я уже сказал, что я думаю, что здесь есть подвох (неявное преобразование?). Подождите минутку, пожалуйста - person sehe; 20.11.2014
comment
@sehe: см. демонстрацию здесь: coliru.stacked-crooked.com/a/01788a718178c6d2 - person Deduplicator; 20.11.2014
comment
Терпение... у вас его нет (исправлено) :) Как бы то ни было, похоже Я неправильно запомнил, и в любом случае это было для operator< (см. здесь). Это та же смешанная перегрузка char* и basic_string<...>. Обратите внимание, однако, что отсутствие вывода другого набора аргументов шаблона позволяет неявно преобразовать тип basic_string соответствующего аргумента, так что это может быть ключевой причиной отказа от вывода разных наборов. - person sehe; 20.11.2014
comment
Давайте продолжим это обсуждение в чате. - person sehe; 20.11.2014