gpt4 book ai didi

c++ - 如何找出lambda的自动类型参数中的哪些方法?

转载 作者:行者123 更新时间:2023-12-05 03:23:57 25 4
gpt4 key购买 nike

我已经与 Boost.Spirit 搏斗了一个星期。请原谅我对 C++ 的模板元编程的无知,但我忍不住要问:如果你不知道一个该死的变量类型,你怎么知道你能用它做什么?例如:

namespace qi = boost::spirit::qi;

qi::on_error<qi::fail>(rule,
[](auto& args, auto& context, auto& r) {
// what to do with args, context and r?
}
);

它不像 Python,你可以在其中使用 dir()help()获取有关某些变量的信息。我知道我可以使用 typeid(..).name()找出变量的类型,但通常结果是一些长的不可读的文本,例如:

struct boost::fusion::vector<class boost::spirit::lex::lexertl::iterator<class boost::spirit::lex::lexertl::functor<struct boost::spirit::lex::lexertl::token<class std::_String_iterator<class std::_String_val<struct std::_Simple_types<char> > >,struct boost::mpl::vector<__int64,struct String,struct Symbol,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na>,struct boost::mpl::bool_<1>,unsigned __int64>,class boost::spirit::lex::lexertl::detail::data,class std::_String_iterator<class std::_String_val<struct std::_Simple_types<char> > >,struct boost::mpl::bool_<1>,struct boost::mpl::bool_<1> > > & __ptr64,class boost::spirit::lex::lexertl::iterator<class boost::spirit::lex::lexertl::functor<struct boost::spirit::lex::lexertl::token<class std::_String_iterator<class std::_String_val<struct std::_Simple_types<char> > >,struct boost::mpl::vector<__int64,struct String,struct Symbol,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na>,struct boost::mpl::bool_<1>,unsigned __int64>,class boost::spirit::lex::lexertl::detail::data,class std::_String_iterator<class std::_String_val<struct std::_Simple_types<char> > >,struct boost::mpl::bool_<1>,struct boost::mpl::bool_<1> > > const & __ptr64,class boost::spirit::lex::lexertl::iterator<class boost::spirit::lex::lexertl::functor<struct boost::spirit::lex::lexertl::token<class std::_String_iterator<class std::_String_val<struct std::_Simple_types<char> > >,struct boost::mpl::vector<__int64,struct String,struct Symbol,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na,struct boost::mpl::na>,struct boost::mpl::bool_<1>,unsigned __int64>,class boost::spirit::lex::lexertl::detail::data,class std::_String_iterator<class std::_String_val<struct std::_Simple_types<char> > >,struct boost::mpl::bool_<1>,struct boost::mpl::bool_<1> > > const & __ptr64,struct boost::spirit::info const & __ptr64>

那么就只剩下一种方法了:引用文档。但问题是:Spirit 的文档不完整。在这个例子中,它只对 "Error Handling Tutorial" 中的这些参数说了几句话。 :

on_error declares our error handler:

on_error<Action>(rule, handler)

...

handler is the actual error handling function. It expects 4 arguments:

Arg Description
first The position of the iterator when the rule with the handler was entered.
last The end of input.
error-pos The actual position of the iterator where the error occurred.
what What failed: a string describing the failure.

但如您所见,on_error的第二个参数不是 4 参数函数,而是 3 参数函数(args、context 和 r)。文档有错吗?我在哪里可以找到这些参数的方法? Spirit 有每个函数的 API 文档吗?

最佳答案

最简单的方法:

qi::on_error<qi::fail>(rule,
[](auto& args, auto& context, auto& r) {
std::cerr << __PRETTY_FUNCTION__ << std::endl;
}
);

例如GCC 这会打印完整的签名,包括推导的类型参数。

文档有误吗?

请注意,它确实需要 4 个参数:

using namespace qi::labels;
qi::on_error<qi::error_handler_result::fail>(rule, f_(_1, _2, _3, _4));

当您安装像 f_ 这样的处理程序时:

struct F {
using result_type = void;

template <typename... Args>
void operator()(Args&&...) const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};

boost::phoenix::function<F> f_{};

它打印 ( Live ):

"expected" -> true
void Parser::F::operator()(Args&& ...) const [with Args = {const char*&, const char* const&, const char* const&, const boost::spirit::info&}]
"unexpected" -> false

如您所见,文档没有错误或不完整。你的期望是,因为你没有得到 handler又名代表一个延迟函数Phoenix Actor .我猜文档所做的“不正当”事情是假设您会从实际示例中看到,它紧接在您引用的文档之前:

on_error<fail>
(
xml
, std::cout
<< val("Error! Expecting ")
<< _4 // what failed?
<< val(" here: \"")
<< construct<std::string>(_3, _2) // iterators to error-pos, end
<< val("\"")
<< std::endl
);

在这里,表达式 std::cout << val("Error! Expecting ") << _4 << val(" here: \"") << construct<std::string>(_3, _2) << val("\"") << std::endl 似乎很明显不是字面上的“一个有 4 个参数的函数”。不过,它是一个 Phoenix 表达式,定义了一个接受 4 个参数的 actor。

确实发现 Actor 实际上仍然是根据可调用对象实现的。它“接受”3 个参数,分别是 Phoenix actors 和 Spirit 上下文参数的技术实现细节。

问题是抽象层次的脱节。文档记录了库接口(interface),你不小心看到了实现细节。

长话短说

lambda 不是延迟的 Phoenix actor。

详细了解延迟参与者的工作原理,例如具有语义 Action :

关于 [SO] 的一些答案突出了 Actor 签名、上下文和实现签名之间的关系:

关于c++ - 如何找出lambda的自动类型参数中的哪些方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72406938/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com