2012-02-10 2 views
3

В руководстве подталкивания :: прото, есть пример грамматики, который соответствует терминалам типа станда :: преобразование < ...>:Могу ли я узнать тип согласованного boost :: proto :: _ в преобразовании?

struct StdComplex 
    : proto::terminal< std::complex<proto::_> > 
{}; 

Я хотел бы написать преобразование, которое делает что-то с тип прото :: _. Например, при сопоставлении proto :: terminal < std :: complex < T>> он возвращает boost :: shared_ptr < T>.

Возможно ли это?

Другой способ сформулировать мой вопрос: как мне сделать следующий сниппет?

template<typename T> 
struct Show : proto::callable 
{ 
    typedef T result_type; 

    result_type operator()(T& v) 
    { 
     std::cout << "value = " << v << std::endl; 
     return v; 
    } 
}; 


struct my_grammar 
: proto::when<proto::terminal<proto::_ >, Show<??? what comes here ???>(proto::_value) > 
{}; 

ответ

3

Ваше шоу преобразование будет легче обрабатывать как полиморфная функция объекта:

struct Show : proto::callable 
{ 
    template<class Sig> struct result; 

    template<class This, class T> 
    struct result<This(T)> 
    { 
    typedef T type; 
    }; 

    template<class T> T operator()(T const& v) const 
    { 
     std::cout << "value = " << v << std::endl; 
     return v; 
    } 
}; 

struct my_grammar 
: proto::when<proto::terminal<proto::_ >, Show(proto::_value) > 
{}; 

Ваш ответ на другой проблемы:

struct to_shared : proto::callable 
{ 
    template<class Sig> struct result; 

    template<class This, class T> 
    struct result<This(T)> 
    { 
    typedef typename T::value_type base; 
    typedef shared_ptr<base> type; 
    }; 

    template<class T> 
    typename result<to_share(T)>::type operator()(T const& v) const 
    { 
    // stuff 
    } 
}; 


struct my_grammar 
: proto::when<proto::terminal<complex<proto::_> >, to_shared(proto::_value) > 
{}; 
+0

Спасибо - очень элегантно! –

+0

Это, похоже, работает для proto :: terminal :: type term1 = {{21}}; , но не proto :: terminal :: type term1 = {{21}}; Я прав? В моем приложении я хочу, чтобы терминал содержал shared_ptr, который указывает на то, что может изменить изменение. Это проблема? Благодарю. –

+0

Ошибка, которую я получаю от компилятора с не-const int: Ссылка на не-const lvalue на тип 'int' не может привязываться к временному типу 'int'. –