Я хочу вернуть VALUE для данного KEY для map <> в c ++.Что возвращать, если KEY отсутствует в карте <>? - PullRequest
1 голос
/ 08 марта 2012

Я написал класс с шаблоном.класс имеет map как член и некоторые функции-члены getxxx () / setxxx ().

template<typename T1,typename T2>
class C1{
    map<T1,T2> M;
public:
    map<T1,T2> getM();
    T2 getMvalue(T1 Key);
    void setM(T1 key,T2 Value);
};

здесь я хочу реализовать getMvalue (), где он получает ключ в качестве аргумента и возвращает соответствующее «значение» ifключ "имеется в mapM.

Это выглядит примерно так ...

template<typename TKey,typename TValue>
T2 C1<T1,T2>::getMvalue(T1 Key){
    if(M.count(Key)>0)
        return M[Key];
    else
        return(???);
};

Здесь мне нужно использовать что-то вместо ???.помните, что возвращаемым типом функции является T2, который может быть любым в зависимости от решения пользователя.Как я могу заменить "???"а с чем?

Ответы [ 4 ]

3 голосов
/ 08 марта 2012

Я бы рекомендовал вам использовать TryGet шаблон

template<typename TKey,typename TValue>
bool C1<T1,T2>::tryGetMvalue(T1 key, T2& value){
    if(M.count(key)>0) {
        value = objProperties[key];
        return true;
    }
    return false;
};
2 голосов
/ 08 марта 2012

Используя operator[], вы уже ограничиваете себя только сохранением значений по умолчанию; так что вы можете вернуть TKey() - если пользователь не должен иметь возможность определить, был ли он на самом деле найден.

Если вам не нужно это ограничение, вам придется изменить его на что-то вроде:

auto found = map.find(key);
if (found != map.end()) {
    return found->second;
} else {
    return ???;
}

Теперь простейшим способом обозначить ошибку является изменение типа возвращаемого значения на указатель (или, возможно, boost::optional, если вы хотите вернуть по значению), и возврат пустого значения (или boost::none); или вернуть результат через опорный параметр и указать успешность с помощью логического возвращаемого значения; или бросить исключение.

2 голосов
/ 08 марта 2012

На ваш выбор три:

  1. throw исключение
  2. Измените подпись, чтобы вы могли возвращать внеполосные данные (это то, что @ JaredPar предлагает )
  3. Вернуть данные в полосе.

Если вы должны выбрать 3, я бы вернул значение по умолчанию(это то, что делает std::map::operator[]):

template<typename TKey,typename TValue>
  T2 C1<T1,T2>::getMvalue(T1 Key){
    if(M.count(Key)>0)
      return M[Key];
    else
      return T2();
  }; 

Осторожно, выбор дизайна № 3 приводит к ошибкам.Вызывающий абонент не может различить «номинальное значение» и «не присутствует».

Ps Если вы вернете значение по умолчанию, ваш код может упроститься до:

template<typename TKey,typename TValue>
T2 C1<T1,T2>::getMvalue(T1 Key){
  return M[key];
}
1 голос
/ 08 марта 2012

Несколько возможностей.Самое простое - заставить указатель возвращать указатель с нулевым указателем, если ключ отсутствует на карте.Кроме того, вы можете сделать так, чтобы он возвращал ошибочный (или, может быть, или как вы его называете);в то время как хорошее решение в целом, кажется, здесь излишнее.Или, наконец, вы можете просто вызвать исключение, если объект отсутствует.

...