Вам не нужен необработанный typedef функции std; Ваш парсер - это больше, чем любая стандартная функция.
struct parser: std::function<parse_result(parse_stream)>{
using base = std::function<parse_result(parse_stream)>;
using base::base;
};
это должно разрешить
parser p = []( parse_stream str ) { return parse_result(7); };
, так как мы используем наследующие конструкторы для представления необработанных std::function
ctors в parser
.
Пока вы можете переопределить:
parser operator&(parser a, parser b) { return both(a,b); }
с версией typedef, поместив &
в пространство имен parse_result
или parse_stream
, я бы посоветовал против этого; в стандарте был чат, чтобы ограничить такого рода аргумент шаблона ADL. С голым типом parser
место для таких перегрузок оператора очевидно.
Кроме того, некоторые типы не могут быть перегружены за пределами класса, например &=
. С struct
вы можете сделать это там.
Ничего из этого не исправлено
parser option = "<" & regexp("[^+>]+");
проблема в том, что правая сторона не имеет представления о том, что делает левая сторона (если regexp
не является функцией, возвращающей парсер).
Сначала сделайте это:
struct parser: std::function<parse_result(parse_stream)>{
using base = std::function<parse_result(parse_stream)>;
parser( char const* str ):
base( [str=std::string(str)](parse_stream stream)->parse_result { /* do work */ } )
{}
parser( char c ):
base( [c](parse_stream str)->parse_result { /* do work */ } )
{}
using base::base;
};
тогда вы можете добавить
namespace parsing {
// parser definition goes here
inline namespace literals {
inline parser operator""_p( char const* str ) { return str; }
}
}
и using namespace parsing::literals
означает, что "hello"_p
- это анализатор, который пытается разобрать строку "hello"
.