其他分享
首页 > 其他分享> > 凤凰中的C boost :: lambda :: ret等效

凤凰中的C boost :: lambda :: ret等效

作者:互联网

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

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

解决方法:

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

让我为像我这样第一次可能会错过你的观点的人做一些阐述.在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

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

using namespace boost::phoenix;

add_t i(38), j(4);
(_1 + _2)(i, j);    // JUST FINE

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

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

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

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;
};

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

using namespace boost::lambda;

ret<add_ret_t>(_1 + _2)(add_t(38), add_t(4)); // OK

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

或者,我想出了一个小的黑客来覆盖特定运算符的返回类型. boost / spirit / home / phoenix / operator / arithmetic.hpp中的result_of_operation模板结构(第39-56行列出结构类型,boost 1.43)在实例化时执行类型推导并存储结果.因此,所需要的只是为问题操作提供一些模板特化,只需要包含一个指定返回类型的typedef.例子(codepad for full 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;
}

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

标签:c,boost-spirit,boost-lambda,boost-phoenix
来源: https://codeday.me/bug/20190726/1546174.html