如何创建Boost Phoenix Make_shared
how to create boost phoenix make_shared?
是否可以创建std::make_shared
的Boost Phoenix懒惰变体?我的意思是,使
namespace p = boost::phoenix;
...
expr = custom_parser[_a=p::make_shared<Node>(_1,_2,_3)] >> ...
由于std::make_shared
的变异模板性质,因此无法使用BOOST_PHOENIX_ADAPT_FUNCTION
。因此,如果可以编写一个。
如果您可以放弃一组额外的括号:
namespace {
template <typename T>
struct make_shared_f
{
template <typename... A> struct result
{ typedef boost::shared_ptr<T> type; };
template <typename... A>
typename result<A...>::type operator()(A&&... a) const {
return boost::make_shared<T>(std::forward<A>(a)...);
}
};
template <typename T>
using make_shared_ = boost::phoenix::function<make_shared_f<T> >;
}
您可以使用
typedef std::vector<int> IntVec;
auto LazyInts = make_shared_<IntVec>()(arg1, arg2);
// create a shared vector of 7 ints '42'
auto ints = LazyInts(7, 42);
for (auto i : *ints) std::cout << i << " ";
请参阅 Live on Coliru
您的phx::make_shared
与phx::construct
非常相似。通过更改construct
的标头文件,您可以得到:
在coliru上跑步
//START OF PHOENIX_MAKE_SHARED.HPP
#ifndef BOOST_PHOENIX_MAKE_SHARED_HPP
#define BOOST_PHOENIX_MAKE_SHARED_HPP
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/phoenix/core/limits.hpp>
#include <boost/phoenix/core/call.hpp>
#include <boost/phoenix/core/expression.hpp>
#include <boost/phoenix/core/meta_grammar.hpp>
#include <boost/phoenix/object/detail/target.hpp>
#include <boost/phoenix/support/iterate.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG(
(boost)(phoenix)(make_shared)
, (proto::terminal<detail::target<proto::_> >)
(meta_grammar)
, BOOST_PHOENIX_COMPOSITE_LIMIT
)
namespace boost { namespace phoenix
{
struct make_shared_eval
{
template <typename Sig>
struct result;
template <typename This, typename A0,typename Context>
struct result<This(A0, Context)>
{
typedef boost::shared_ptr<typename detail::result_of::target<A0>::type > type;
};
template <typename Target, typename Context>
typename boost::shared_ptr<typename detail::result_of::target<Target>::type>
operator()(Target, Context const &) const
{
return boost::make_shared<typename detail::result_of::target<Target>::type>();
}
#define EVAL_a(_,N,__)
BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) boost::phoenix::eval(a ## N, ctx)
#define GENERATE_MAKE_SHARED_EVAL(_,N,__)
template <typename This, BOOST_PHOENIX_typename_A(N), typename Context>
struct result<This(BOOST_PHOENIX_A(N), Context)>
{
typedef boost::shared_ptr<typename detail::result_of::target<A0>::type > type;
};
template <BOOST_PHOENIX_typename_A(N), typename Context>
typename boost::shared_ptr<typename detail::result_of::target<A0>::type >
operator()(
A0 const&
, BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(
N
, A
, const& a
)
, Context const & ctx
) const
{
return
boost::make_shared<typename detail::result_of::target<A0>::type>(
BOOST_PP_REPEAT_FROM_TO(
1
, N
, EVAL_a, _
)
);
}
BOOST_PP_REPEAT_FROM_TO(2,BOOST_PHOENIX_COMPOSITE_LIMIT,GENERATE_MAKE_SHARED_EVAL,_)
#undef EVAL_a
#undef GENERATE_MAKE_SHARED_EVAL
};
template <typename Dummy>
struct default_actions::when<rule::make_shared, Dummy>
: call<make_shared_eval, Dummy>
{};
template <typename T>
inline
typename expression::make_shared<detail::target<T> >::type const
make_shared()
{
return
expression::
make_shared<detail::target<T> >::
make(detail::target<T>());
}
#define GENERATE_MAKE_SHARED(_,N,__)
template <typename T, BOOST_PHOENIX_typename_A(N)>
inline
typename expression::make_shared<detail::target<T>, BOOST_PHOENIX_A(N)>::type const
make_shared(BOOST_PHOENIX_A_const_ref_a(N))
{
return
expression::
make_shared<detail::target<T>, BOOST_PHOENIX_A(N)>::
make(detail::target<T>(), BOOST_PHOENIX_a(N));
}
BOOST_PP_REPEAT_FROM_TO(1,BOOST_PHOENIX_COMPOSITE_LIMIT,GENERATE_MAKE_SHARED,_)
#undef GENERATE_MAKE_SHARED
}}
#endif
//END OF PHOENIX_MAKE_SHARED.HPP
#include <iostream>
#include <string>
#include <vector>
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace phx=boost::phoenix;
namespace qi=boost::spirit::qi;
struct foo
{
foo():foo1(1),foo2(1.1){}
foo(int foo1_):foo1(foo1_),foo2(2.2){}
foo(int foo1_, double foo2_):foo1(foo1_),foo2(foo2_){}
int foo1;
double foo2;
};
int main()
{
//using phx::arg_names::arg1;
//using phx::arg_names::arg2;
//boost::shared_ptr<foo> var1 = phx::make_shared<foo>()();
//boost::shared_ptr<foo> var2 = phx::make_shared<foo>(arg1)(2);
//boost::shared_ptr<foo> var3 = phx::make_shared<foo>(arg1,arg2)(3,3.3);
//std::cout << "var1: " << var1->foo1 << ", " << var1->foo2 << std::endl;
//std::cout << "var2: " << var2->foo1 << ", " << var2->foo2 << std::endl;
//std::cout << "var3: " << var3->foo1 << ", " << var3->foo2 << std::endl;
std::string test = "default,2,3-3.3";
qi::rule<std::string::const_iterator,boost::shared_ptr<foo>()> awful_rule =
qi::lit("default")[qi::_val=phx::make_shared<foo>()]
| (qi::int_ >> !qi::lit('-'))[qi::_val=phx::make_shared<foo>(qi::_1)]
| (qi::int_ >> qi::lit('-') >> qi::double_)[qi::_val=phx::make_shared<foo>(qi::_1,qi::_2)]
;
qi::rule<std::string::const_iterator,std::vector<boost::shared_ptr<foo> >()> parser = awful_rule%qi::lit(',');
std::string::const_iterator iter=test.begin(), end=test.end();
std::vector<boost::shared_ptr<foo> > foo_vector;
bool result = qi::parse(iter, end, parser, foo_vector);
if(result && (iter==end) )
{
std::cout << "Success:" << std::endl;
for(std::size_t cont=0; cont < foo_vector.size(); ++cont)
std::cout << foo_vector[cont]->foo1 << ", " << foo_vector[cont]->foo2 << std::endl;
}
else
{
std::cout << "Failure. Unparsed: " << std::string(iter,end) << std::endl;
}
}
相关文章:
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- make 命令如何避免重新编译未更改的源文件?
- MAKE:找不到包含的用户定义的头文件?
- 'make check' GLIBC 运行时的链接问题
- Qt5 [make -snap] 无法正确编译:进程"/usr/bin/snap"代码 1 退出
- mingw32-make 使用"MinGW Makefiles"生成器跟踪 CMAKE 无法将可执行文件链接到对象库
- make 命令创建 .file,但不创建应用程序文件
- 如何摆脱导入的 make 项目中的 Eclipse 索引器"Type std::... could not be resolved"错误
- Qt Creator 在执行步骤 "make" 时出现编译错误,-fno-stack-limit
- 如何使用MySQL Connector and Make设置C++项目
- 使用 make 将对象文件放在特定目录中
- 我是 C++ 的新手,我试图调用 make 一个以 2 个类作为其参数的类构造函数
- "Make"失败并出现 Clang 错误 - 如何从 Clang 获得错误?
- 防止 GNU Make 在每次构建时生成 protobuf 代码
- Make zmqpp::socket::connect a std::future
- 链接从命令行转换为Make的库
- 将 make 和 cmake 合并到构建系统中
- 使用 CMake (make) 和 GCC 构建和编译 gSOAP 项目
- Cassandra C++ MacOS High Sierra上的驱动程序:make:没有规则来制作目标