Использовать аргумент шаблона функции в качестве аргумента шаблона класса? - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь познакомиться с шаблонами в C ++, реализовав что-то похожее на Linq в C #.В конце концов, запрос данных должен выглядеть примерно так:

SomeIteratorType begin = /* ... */;
SomeIteratorType end = /* ... */;
typedef iterator_traits<SomeIteratorType>::value_type Type;

linq<int> query = linq<Type>(begin, end)
                  .where([](Type value) -> bool { return /* ... */; })
                  .select([](Type value) -> int { return value.some_property; });

for (int value : query)
    cout << value << endl;

Я начал с

template<typename Type>
class linq : public std::iterator<std::input_iterator_tag, Type> {
public:
    typedef bool (WherePredicate)(Type value);

    // ...
    // Copy-constructor, operator=, operator++, ...
    // ...

    // ...
    // Linq functions, e.g.
    linq& where (WherePredicate& predicate) const; // returns some specialization of the linq-class (should probably not name this "where")
    // ...
};

Но как объявить конструктор linq(begin, end) из примера?Если begin и end имеют тип IteratorType, мне нужно, чтобы результирующий объект linq был типа linq<std::iterator_traits<IteratorType>::value_type>.Можно ли даже определить аргумент шаблона класса из аргумента шаблона функции?Если нет, возможно ли, по крайней мере, гарантировать, что IteratorType begin и IteratorType end достаточно std::iterator_traits<IteratorType>::value_type == Type, при использовании, как linq<Type>(begin, end)?

1 Ответ

0 голосов
/ 20 мая 2018

Таким образом, C # использует объекты, выделенные в куче, и перенаправление через интерфейсы, как если бы оно было бесплатным.

Если вы хотите эмулировать это, вы должны сделать то же самое.Если вам также нужна семантика значений, вам нужно написать оболочки, которые содержат умные указатели и ведут себя как значения.

Другой подход состоит в том, чтобы не вводить стирание;вместо этого объект linq является уникальным типом для каждой цепочки модификаторов.Здесь linq - это функция, не являющаяся типом, и вы сохраняете возвращаемые значения в auto переменных.

Эти два подхода могут работать вместе, как лямбда (без вызова типа ersaure) и функция std (тип значения, которыйможет выделять кучу и стирать типы при конструировании, чтобы забыть все, кроме вызова интерфейса вызываемого объекта).

Чтобы получить дальнейшие сведения, узнайте об удалении типов (включая способ написания функции std), регулярных типах в C ++ и, возможно, изучитеRangesv3 - библиотека, поддерживающая потоковые выражения в стиле linq.

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