Вы можете избежать этой проблемы и сделать код более надежным и выразительным, преобразовав индекс в другой тип, который проясняет, чего хочет пользователь. Использование было бы так:
bidirectional_map<int, int> myTest;
int& valueFor1 = myTest[Key{1}];
int& key1 = myTest[Value{valueFor1}];
Реализовано так:
template<class TKey>
struct Key { const TKey& key; };
template<class TValue>
struct Value { const TValue& value; };
// Deduction guides (C++17), or use helper functions.
template<class TValue>
Value(const TValue&) -> Value<TValue>;
template<class TKey>
Key(const TKey&) -> Key<TKey>;
template<class TKey, class TValue>
class bidirectional_map
{
TKey a1; // Probably arrays
TValue a2; // or so?
public:
TValue & operator[](Key<TKey> keyTag) { const TKey & key = keyTag.key; /* ... */ }
TKey & operator[](Value<TValue> valueTag) { const TValue& value = valueTag.value; /* ... */ }
};
Теперь Key
и Value
являются популярными именами, поэтому их использование этими вспомогательными функциями не является лучшим. Кроме того, это всего лишь довольно теоретическое упражнение, потому что функции-члены, конечно, намного лучше подходят для этой задачи:
template<class TKey, class TValue>
class bidirectional_map
{
TKey a1; // Probably arrays
TValue a2; // or so?
public:
TValue& getValueForKey(const TKey& key) { /* ... */ }
TKey& getKeyForValue(const TValue& value) { /* ... */ }
};