我希望通过使用模板参数指定do_eval
转换的返回类型(迄今为止double
)来构建来自here的Boost Proto“解包表达式”示例
为简洁起见,我将提供do_eval
的工作,简化(仅限加)版本:
struct do_eval2 : proto::callable
{
typedef double result_type;
template <typename X, typename Y>
result_type operator()(proto::tag::plus, X x, Y y) const { return x + y; }
};
然后我添加模板参数T
而不是double
:
template <typename T>
struct do_eval2 : proto::callable
{
typedef T result_type;
template <typename X, typename Y>
result_type operator()(proto::tag::plus, X x, Y y) const { return x + y; }
};
并将关联的eval
结构修改为:
struct eval2
: proto::or_<
proto::when<proto::terminal<proto::_>, proto::_value>
, proto::otherwise<do_eval2<double>(proto::tag_of<proto::_>(),
eval2(proto::pack(proto::_))...)>
>
{};
但是当我使用它时,如下面的代码所示,我从错误开始出错:无法将'std :: ostream {aka std :: basic_ostream}'左值绑定到'std :: basic_ostream&amp;&amp; ;'如何满足编译器?
int main(int argc, char *argv[])
{
int one = 1, two = 2;
cout << eval2()(phoenix::ref(one)+phoenix::ref(two)) << '\n';
return 0;
}
答案 0 :(得分:4)
正如您所见here:
转换的形式通常为proto :: when&lt;东西,R(A0,A1,...)&gt;。问题是R是代表要调用的函数还是要构造的对象,答案决定了proto :: when&lt;&gt;评估变换。原::当&LT;&GT;使用proto :: is_callable&lt;&gt;两者之间消除歧义的特征。 Proto尽力猜测一个类型是否可以调用,但它并不总是正确的。最好知道Proto使用的规则,以便您知道何时需要更明确。
对于大多数类型R,proto :: is_callable检查proto :: callable的继承。但是,如果类型R是模板特化,则Proto假定即使模板继承自proto :: callable,它也不可调用。
文档提出了解决方案:您可以使用do_eval<double>
包装每个proto::call
的调用,或者只是在boost :: proto命名空间中专门化is_callable
并忘记问题。
namespace boost { namespace proto
{
// Tell Proto that do_eval2<> is callable
template<typename T>
struct is_callable<do_eval2<T> >
: mpl::true_
{};
}}
[编辑:]这是proto::call
替代方案:
struct eval2
: proto::or_<
proto::when<proto::terminal<proto::_>, proto::_value>
, proto::otherwise<
proto::call<do_eval2<double>(proto::tag_of<proto::_>(),
eval2(proto::pack(proto::_))...)>>
>
{};
答案 1 :(得分:4)
请参阅上一个答案。我还补充说,另一种解决方案是定义do_eval2
,如下所示:
template <typename T, typename D = proto::callable>
struct do_eval2 : proto::callable
{
typedef T result_type;
template <typename X, typename Y>
result_type operator()(proto::tag::plus, X x, Y y) const { return x + y; }
};
请注意额外的虚拟模板参数。
编辑:此外,在目前正在开发的Proto的下一个版本中,您将不需要了解这块奥秘,并且应该只需要工作。我将在几周内在C ++上谈论它。