Boost lambda允许使用ret<T>
模板覆盖推断的返回类型。
我曾尝试在凤凰中搜索等效物,但找不到它。
凤凰有没有相同的东西?我知道怎么做自己的替换,但我宁愿不做。谢谢
答案 0 :(得分:8)
重写:我错过了第一个回答的问题(已经很晚了),让我再试一次。
让我为像我这样第一次可能会错过你的观点的人做一些阐述。在boost :: lambda中,当在运算符表达式中使用用户定义的类型时,必须使用ret&lt;&gt;函数覆盖返回类型推导。这是因为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_ 操作模板结构(第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;
}
这肯定不是替代品,但从某种意义上来说,它的全球化程度更高。如果有很多运算符需要重载,则可以对整个操作集进行宏操作。
答案 1 :(得分:0)
AFAIK,凤凰城不支持此(或类似的东西)。如果您描述了您的用例,我可能会提供帮助。