C++ boost :: lambda :: ret等效于凤凰

Any*_*orn 3 c++ boost-spirit boost-lambda boost-phoenix

Boost lambda允许使用ret<T>模板覆盖推断的返回类型.我曾尝试在凤凰中搜索等效物,但找不到它.

在凤凰中有相同的东西吗?我知道怎么做自己的替换,但我宁愿不做.谢谢

aca*_*bot 8

重写:我错过了我的第一个答案(已经很晚了),让我再试一次.

让我为像我这样第一次可能会错过你的观点的人做一些阐述.在boost :: lambda中,当在运算符表达式中使用用户定义的类型时,必须使用ret <>函数来覆盖返回类型推导.这是因为lambda返回类型推导系统仅直接支持本机(和stl?我不记得)类型.一个简短的例子:

using namespace boost::lambda;

struct add_t{
    add_t(int i) : i(i) {};
    add_t operator+(const add_t& other) const{
        return add_t(i + other.i);
    }
    int i;
};

(_1 + _2)(add_t(38), add_t(4));           // RETURN TYPE DEDUCTION FAILS
ret<add_t>(_1 + _2)(add_t(38), add_t(4)); // OK
Run Code Online (Sandbox Code Playgroud)

但是在凤凰城中,不需要任何提示(请注意,文字和非常设临时数不能出现在凤凰参数列表中):

using namespace boost::phoenix;

add_t i(38), j(4);
(_1 + _2)(i, j);    // JUST FINE
Run Code Online (Sandbox Code Playgroud)

返回式演绎系统完全不同,在凤凰中更自然; 它将适当地推导出使用传统语义的运算符的返回类型.具体来说,返回类型应该与其中一个操作数的类型匹配,是指向其中一个参数类型的引用,指针或const指针,或者是其中一个类型的stl容器/容器迭代器.有关更多详细信息,请在type_deduction.hpp标题中详细介绍phoenix返回类型推导.

所以现在我正在读你的问题,如何在凤凰中处理非传统的算子语义?

以下面一对奇怪的类型为例

struct add_ret_t{
    add_ret_t(int i) : i(i) {};
    int i;
};

struct add_t{
    add_t(int i) : i(i) {};
    add_ret_t operator+(const add_t& other) const{
        return add_ret_t(i + other.i);
    }
    int i;
};
Run Code Online (Sandbox Code Playgroud)

对于lambda,这没问题,只需使用ret函数:

using namespace boost::lambda;

ret<add_ret_t>(_1 + _2)(add_t(38), add_t(4)); // OK
Run Code Online (Sandbox Code Playgroud)

但是凤凰无法处理这个运算符(你可以怪吗?)因为返回类型与参数无关,并且无法直接指示凤凰中的返回类型.如果有充分的理由使用这样的运算符,可以在类型推导系统中添加一个案例,但是如果不破解type_deduction.hpp或分支好凤凰的一部分,我就看不到这样做的方法.

或者,我想出了一个小的黑客来覆盖特定运算符的返回类型.boost/spirit/home/phoenix/operator/arithmetic.hpp中的result_of_ 操作模板结构(第39-56行列出结构类型,boost 1.43)在实例化时执行类型推导并存储结果.因此,所需要的只是为问题操作提供一些模板特化,只需要包含一个指定返回类型的typedef.示例(完整src的键盘):

using namespace boost::phoenix;

namespace boost{ namespace phoenix{

//override add_t addition to give add_ret_t
template <> struct result_of_plus<add_t&, add_t&> { typedef add_ret_t type; };

//override int addition to give char
template <> struct result_of_plus<int&, int&> { typedef char type; };

}}

int main()
{
    add_t i = 1, j = 7;
    std::cout << ((_1 + _2)(i, j)).i << std::endl;

    int k = 51, l = 37;
    std::cout << ((_1 + _2)(k, l)) << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这肯定不是替代品,但从某种意义上来说,它的全球化程度更高.如果有许多运算符过载,则可以对整个操作集进行宏.