Я работаю над библиотекой комбинатора синтаксического анализатора, и у меня есть класс, который определяет, что такое синтаксический анализатор:
template <typename P, typename allow=void>
struct parser;
Что я частично специализируюсь на двух вещах:
- построить парсер из строкового литерала для удобства
- в противном случае обернуть функцию синтаксического анализа (которая вызывается)
Если я могу это сделать, тогда я могуиспользуйте is_convertible<T, parser<T>>
в качестве предиката для моих комбинаторов, чтобы запретить их использование для всего, что не является «парсером».
Строка проста:
template <>
struct parser<string> {
...
};
Но, в общем, парсер - это простоcallable, который принимает parse_stream и возвращает необязательный результат (я нахожусь на c ++ 11, поэтому у меня фактически нет std :: option, но мы будем притворяться).Итак, что-то вроде этого:
template <typename Result>
using parser_callable = function<optional<Result>(parse_stream)>;
Так, как я могу сделать частичную специализацию шаблона для вызываемого с неизвестным типом возврата?Замечание: я не хочу преобразовывать в std :: function, просто это совместимая вызываемая «вещь».
Edit, вот пример моей идеальной возможности, если бы у нас был какой-то подтип Scala-ishограничения и сопоставление с образцом ...
template <P <: optional<R>(parse_stream)>
struct parser<P> {
parser(P p) : p_(p) {}
optional<R> operator(parse_stream stream) {
p_(stream);
}
private:
P p_;
};