2012-03-19 5 views
6

У меня проблема с переносом моего функтора из окон в linux. (Функтор перейти к СТЛ :: карта для строгого слабой упорядоченности) Оригинал следующим образом:Ошибка: передача const xxx, поскольку этот аргумент xxx отбрасывает квалификаторы

struct stringCompare{ // Utilized as a functor for stl::map parameter for strings 
    bool operator() (string lhs, string rhs){ // Returns true if lhs < rhs 
     if(_stricmp(lhs.c_str(), rhs.c_str()) < 0) return true; 
     else return false; 
    } 
}; 

Как линукс оленья кожа поддержки _stricmp но использует strcasecmp вместо этого, я изменил его:

struct stringCompare{ 
    bool operator() (string lhs, string rhs){ // Returns true if lhs < rhs 
     if(strcasecmp(lhs.c_str(), rhs.c_str()) < 0) return true; 
     else return false; 
    } 
}; 

И теперь жалуется на «константных» параметров:

passing const stringCompare as this argument of bool stringCompare::operator() 
(std::string, std::string)â discards qualifiers 

Я не совсем уверен, почему он допускает stringCompare должно быть постоянным ...

И линия, где она с ума по этому поводу быть экземпляр является:

if(masterList->artistMap.count(songArtist) == 0) 

artistMap будучи СТЛ :: карта с ключом строки.

Я не уверен, где я ошибаюсь. Я попытался изменить параметры bool operator() на const, так как кажется, что он жалуется на некоторую непереходную передачу параметров. Это не сработало и не изменило «bool operator()» на «const bool operator()».

Насколько я знаю, strcasecmp - это функция const, поэтому следует учитывать, передаю ли я ей непостоянные или постоянные параметры (c_str() также является константой), поэтому я не совсем уверен, где я ошибаюсь ,

У меня есть аналогичные проблемы с Google, но я все еще не могу понять смысл этой проблемы из того, что я видел как в stackoverflow, так и в нескольких других местах.

Тип данных, где я использую это:

map<string, set<song, setSongCompare>*,stringCompare > artistMap; 
+0

Может быть связано с 'const' классификатором ?? Предупреждение сообщается в декларации 'map' или где-то еще? – Kashyap

+0

Вам намного лучше использовать строковые алгоритмы, которые переносятся и работают на std :: string, а не на const char *. есть одно для случая нечувствительного сравнения. – 111111

+0

сообщается на эту строку: если (мастерList-> художникMap.count (songArtist) == 0) , где songArtist - это строка – Glem

ответ

10

Две вещи:

  1. определить свой bool operator() в const. Это просто хорошая практика. Это говорит компилятору, что эта функция не будет иметь побочных эффектов для переменных-членов класса.

  2. Добавить const & квалификаторы в lhs и rhs аргументы. Хорошая практика - передача постоянных ссылок вместо копирования всей памяти. Объявляя ссылки как const, вы сообщаете компилятору, что эта функция не должна иметь побочных эффектов для ссылочных объектов.

Ваш operator() должен выглядеть следующим образом:

bool operator() (const string &lhs, const string &rhs) const 
{ 
    return strcasecmp(lhs.c_str(), rhs.c_str()) < 0; 
} 
+0

Как я уже упоминал, я попробовал это, и он дает тот же результат. – Glem

+1

@Glem Не 'const bool operator() (...)' but 'bool operator() (...) const' – Praetorian

+0

Я думал, что пытался это сделать, но, полагаю, нет! Это работало. Зачем нужен параметр const после параметров? Я этого раньше не видел. Кроме того, разве теоретически не стоит беспокоиться о const, если ни одна из внутренних функций не является постоянной? Просто чтобы я мог прояснить в моей голове, почему произошла ошибка. Спасибо! – Glem