Шаблонный оператор [] ... возможно?Полезно? - PullRequest
2 голосов
/ 04 марта 2010

Не могли бы вы:

template <class T>
const T &operator[] (unsigned int x)

Я подумал, что если у вас есть map<string,string>, было бы неплохо иметь класс-обертку, который позволяет вам:

obj["IntVal"]="12";
obj["StringVal"]="Test";

int i = obj["IntVal"];

Насколько близко к этому мы можем фактически прийти в C ++? Это стоит боли?

Ответы [ 6 ]

5 голосов
/ 04 марта 2010

Вы также можете сделать

class Class {
  struct Proxy {
    template<typename T> T as() { ... }
    template<typename T> operator T() { return as<T>(); }
  private:
    Proxy(...) { ... }
    Proxy(Proxy const&); // noncopyable
    Proxy &operator=(Proxy const&);
    friend class Class;
  };

public:
  Proxy operator[](std::string const& s) { ... }
};

Class a;
int i = a["foo"];
int i = a["foo"].as<int>();

T будет выведено на любой объект, который будет инициализирован. И вам не разрешено копировать прокси. Тем не менее, я предпочитаю явную функцию as<T>, как и другую, предложенную тоже.

4 голосов
/ 04 марта 2010

Вы не можете - в:

int i = obj["IntVal"]; 

фактический тип T не может быть выведен из контекста, поскольку возвращаемый тип не является частью сигнатуры функции.

Более того, хранение целочисленных значений в виде строк не считается наилучшей практикой из-за соображений памяти и производительности; -)

2 голосов
/ 04 марта 2010

Не стоит.

Создание шаблона возвращаемого типа означает, что вам придется явно указывать параметр шаблона при его вызове. Примерно так, возможно у меня неправильный синтаксис:

int i = obj.operator[]<int>("IntVal");

C ++ не выводит параметры шаблона из того, чему вы назначаете результат вызова, только из параметров, с которыми вы вызываете функцию.

Так что вы можете просто определить нормальную функцию:

int i = obj.get<int>("IntVal");

Или в этом случае либо сделайте это, либо внедрите get, используя это:

int i = boost:lexical_cast<int>(obj["IntVal"]);

Как говорит Амит, вы можете определить operator[] для возврата типа, который может быть преобразован либо в int, либо в другие типы. Затем ваш пример кода может быть скомпилирован без явного lexical_cast.

0 голосов
/ 04 марта 2010

Карта уже содержит перегруженную operator[], которая выполняет большую часть того, что вы хотите. Кажется, вам не хватает неявного преобразования строки, содержащей цифры в целое число. Одной из фундаментальных характеристик C ++ является статическая типизация, которая говорит, что это не должно быть разрешено - так что это не так. Если вы захотите, он будет рад сделать это, но вам придется попросить об этом:

int i = lexical_cast<int>(obj["IntVal"]);

Кроме того, вы можете создать строковый класс, который поддерживает неявное преобразование в int. Лично я бы посоветовал против этого. Я не возражаю против неявных преобразований почти так же сильно, как это делают многие люди, но это все равно кажется мне довольно паршивой идеей, по крайней мере, для наиболее общего использования.

0 голосов
/ 04 марта 2010

Ну, то, что вы написали в своем примере кода, не соответствует вопросу.Прямо сейчас у вас есть только тип возвращаемого значения.

Но если вы хотите сделать что-то вроде:

template <class T>
const T &operator[const T& x]

, это действительно, хотя, возможно, не очень полезно.

0 голосов
/ 04 марта 2010

Вы смотрели на вариант усиления ? Это то, что вы ищете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...