#c
#c
Вопрос:
Я сталкиваюсь с проблемами, когда пытаюсь использовать эту operator ()
функцию в классе для строкового объекта вместо символа или числового типа данных. Я попробовал следующую реализацию , чтобы проверить, являются ли повторяющиеся данные a std::string
, но функция по-прежнему возвращает ошибку при выполнении этой части кода:
this-gt;current -= this-gt;range-gt;step;
Это имеет смысл, смысл в том , что вы не можете выполнить эту операцию над a std::string
, однако мой текущий метод создания исключения для строк работает не совсем правильно, он продолжает выбрасывать:
error: no match for 'operator-=' (operand types are 'std::__cxx11::basic_stringlt;chargt;' and 'std::__cxx11::basic_stringlt;chargt;' this-gt;current -= this-gt;range-gt;step;
Есть какие-нибудь идеи по лучшей реализации или, возможно, по-другому написать этот код?
Iteratoramp; operator () { bool isStr = false; std::string str = "s"; auto cmp = this-gt;range-gt;step; if (typeid(cmp) == typeid(str)) { // check if the variable is a string isStr = true; } if (this-gt;range-gt;stop gt; this-gt;range-gt;start || isStr) { // if increasing, or working w/ strings this-gt;current = range-gt;step; return *this; } else if (this-gt;range-gt;stop lt; this-gt;range-gt;start) { // if decreasing if (!isStr) { this-gt;current -= this-gt;range-gt;step; } } return *this; }
Ответ №1:
Как и ваш код, он не завершен и не будет компилироваться. Но при работе с кодом, который должен делать выбор в зависимости от типа, используйте конструкции времени компиляции! Используйте такие вещи, как «перегрузка», «шаблоны», «если constexpr», «SFINAE». Например :
#include lt;type_traitsgt; #include lt;stringgt; struct foo_t { templatelt;typename type_tgt; autoamp; operator () { if constexpr (std::is_same_vlt;type_t, std::stringgt;) // lt;== check types at compile time! { // working with strings we go only one way current = range-gt;step; } else { // if increasing if (range-gt;stop gt; range-gt;start ) { current = range-gt;step; } else if (range-gt;stop lt; range-gt;start) { current -= range-gt;step; } } return *this; } };
Ответ №2:
Вы проверяете тип во время выполнения, что не сработает. Вместо этого вам нужно проверить тип во время компиляции.
В C 17 и более поздних версиях вы можете использовать if constexpr
для этого, например:
#include lt;type_traitsgt; Iteratoramp; operator () { if constexpr (std::is_same_vlt;decltype(range-gt;step), std::stringgt;) { // check if the variable is a string current = range-gt;step; } else if (range-gt;stop gt; range-gt;start) { // if increasing current = range-gt;step; } else if (range-gt;stop lt; range-gt;start) { // if decreasing current -= range-gt;step; } return *this; }
В более ранних версиях C вместо этого вам придется перегружать оператор с помощью SFINAE ( std::enable_if()
и т. Д.) Или специализации шаблона, чтобы изолировать std::string
версию оператора в отдельную реализацию.