Как правильно нарисовать? (Или я должен это делать?)

Если у меня есть код, например

class CString { int GetLength(); };

bool smaller(CString s1, std::string s2) {
    return s2.size() > s1.GetLength();
}

Что мне лучше делать?

  • Измените s1.GetLength() на (size_t)c.GetLength()?
    Это поможет избавиться от предупреждения компилятора относительно "несоответствия без подписей" и сообщить о моем намерении бросить, и это самый простой способ. Но он, вероятно, нахмурился.: (

  • Измените s1.GetLength() на static_cast<size_t>(c.GetLength())?
    Это поможет избавиться от предупреждения с помощью "The Correct".

  • Измените s1.GetLength() на static_cast<std::string::size_type>(c.GetLength())?
    Это чрезвычайно многословное... есть ли практическая польза для этой абстракции, или я должен ее нарушить?

  • Оставьте это как есть?
    Это поможет сделать компилятор переполнением с помощью переключателя /RTCc (моя главная проблема здесь), за счет предупреждения.

  • Сделайте что-нибудь еще?
    Должен ли я сделать свою собственную функцию кастинга? Использовать макрос? Должен ли я проверять время выполнения и время компиляции? Любые другие идеи?

Edit:

Кажется, что пример берется слишком буквально...

Я, очевидно, не хотел говорить примерно CString::GetLength(). Этот конкретный метод, конечно, не вызывает большого беспокойства.:) То, что меня беспокоит, - это более общий случай, когда я получаю целое число, которое никогда не должно быть отрицательным, но которое теоретически может быть связано с ошибками.

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

В таком случае, что мне делать?

Ответ 1

Можете ли вы изменить GetLength()? По сути, проблема в том, что длина никогда не является отрицательной, а неподписанный тип отражает лучшее. Длина не должна измеряться с помощью int.

Но кроме этого все три ваших решения идентичны. std::string::size_type всегда std::size_t, и, хотя я бы использовал static_cast, в этом случае приведение в стиле C будет выполняться в том же режиме. Поскольку вы знаете, что возвращаемая длина никогда не является отрицательной (убедитесь, что это, кстати, вы никогда не знаете, какие странные вещи могут сделать люди), вы полностью безопасны, просто набрасывая тип:

return s2.size() > static_cast<std::size_t>(s1.GetLength());

Если CString::GetLength может быть отрицательным, по какой-то причине, то вам решать, как сделать это преобразование с отрицательного на положительное. Обрезать? Величина (абсолютное значение)? Все, что вам нужно.


Если вы беспокоитесь об ошибках, либо выполните явную проверку, либо исключите исключение (в зависимости от вашего домена, это может быть слишком дорого) или используйте assert. Как правило, вы должны доверять документации.

Ответ 2

Поместите бросок в свою собственную функцию с комментарием:

std::string::size_type size(const CString& mfcString)
{
    // CString::GetLength is always non-negative
    // http://msdn.microsoft.com/en-us/library/aa300471(v=vs.60).aspx

    return static_cast<std::string::size_type>(mfcString.GetLength());
}

Тогда ваш код будет:

bool smaller(const CString& s1, const std::string& s2)
{
    return size(s1) < s2.size();
}

Ответ 3

Я бы сказал, что правильное решение - изменить подпись CString::getLength(), чтобы вернуть неподписанный тип. Учитывая, что вы используете аргументы по стоимости, вы можете рассмотреть возможность создания конструктора преобразования для CString с помощью std::string (возможно, вы, вероятно, должны изменить подпись вашей функции, чтобы принять ее аргументы const&).

Лично я бы рассматривал операцию как конверсию, а не как литье, и записывал ее как таковую:

return std::string::size_type(s1.getLength())
    < s2.size();

Ответ 4

измените метод CString:: getLength() и верните неподписанный тип.

попробуйте это

return std::string:: size_type (s1.getLength())   < s2.size();