我可以给出不同的行为来提升::p roto::标签类型吗?
Can I give different behaviours to boost::proto::tag types?
我正在尝试使用boost proto来懒惰地评估表达式,我想做的是能够为+,-,函数等标签赋予不同的行为。
function(
terminal(8functionILi2EE)
, plus(
multiplies(
terminal(6tensorILi0EE)
, terminal(6tensorILi1EE)
)
, multiplies(
terminal(6tensorILi2EE)
, terminal(6tensorILi3EE)
)
)
)
对于像上面这样的树,我希望能够指定每个树节点的行为方式。
例如。
struct context : proto::callable_context< context const >
{
// Values to replace the tensors
std::vector<double> args;
// Define the result type of the zero.
// (This makes the zero_context "callable".)
typedef double result_type;
// Handle the tensors:
template<int I>
double operator()(proto::tag::terminal, tensor<I>) const
{
std::cout << this->args[I] << std::endl;
return this->args[I];
}
template<int I>
void operator()(proto::tag::plus) const
{
std::cout << " + " << std::endl;
}
};
当我这样做时
double result = (_tensorA + _tensorB)(10, 20);
我希望我的输出是
10
+
20
但这只是
10
20
任何帮助将不胜感激! :)
template<int I>
void operator()(proto::tag::plus) const
{
std::cout << " + " << std::endl;
}
模板参数I
是不可推导的,因此重载将永远不适用。删除模板参数:
void operator()(proto::tag::plus) const
{
std::cout << " + " << std::endl;
}
但是,您真正想要的是拦截二进制运算符。井。请注意,它是二进制的。所以它有两个参数:
template<size_t I, size_t J>
void operator()(proto::tag::plus, proto::literal<tensor<I>>&, proto::literal<tensor<J>>&) const {
std::cout << " + " << std::endl;
}
住在科里鲁
但是,这会阻止表达式树的进一步计算。不是你想要的,对吧。因此,让我们做一个简单的重新实现:
template<size_t I, size_t J>
double operator()(proto::tag::plus, proto::literal<tensor<I>>& a, proto::literal<tensor<J>>& b) const {
auto va = (*this)(proto::tag::terminal{}, a.get());
std::cout << " + " << std::endl;
auto vb = (*this)(proto::tag::terminal{}, b.get());
return va + vb;
}
住在科里鲁
通用,请
但是,有些东西告诉我你想要泛型表达式。所以t1 + (t2 + t3)
也应该有效,但(t2 + t3)
不是字面意思......
让我们通过委派来简化:
template<typename A, typename B>
double operator()(proto::tag::plus, A& a, A& b) const {
auto va = proto::eval(a, *this);
std::cout << " + " << std::endl;
auto vb = proto::eval(b, *this);
return va + vb;
}
完整样本
住在科里鲁
#include <boost/proto/proto.hpp>
#include <vector>
namespace proto = boost::proto;
template <size_t N> struct tensor { };
template <size_t N, size_t M> tensor<N+M> operator+(tensor<N>, tensor<M>) { return {}; }
struct context : proto::callable_context< context const >
{
using base_type = proto::callable_context<context const>;
// Values to replace the tensors
std::vector<double> args { 0, 111, 222, 333 };
// Define the result type of the zero.
// (This makes the zero_context "callable".)
typedef double result_type;
// Handle the tensors:
template<size_t I>
double operator()(proto::tag::terminal, tensor<I>) const
{
std::cout << this->args[I] << std::endl;
return this->args[I];
}
template<typename A, typename B>
double operator()(proto::tag::plus, A& a, B& b) const {
auto va = proto::eval(a, *this);
std::cout << " + " << std::endl;
auto vb = proto::eval(b, *this);
return va + vb;
}
};
int main() {
proto::literal<tensor<1> > t1;
proto::literal<tensor<2> > t2;
proto::literal<tensor<3> > t3;
auto r = proto::eval(t1 + (t2 + t3), context());
std::cout << "eval(t1 + (t2 + t3)) = " << r << "n";
}
指纹
111
+
222
+
333
eval(t1 + (t2 + t3)) = 666
相关文章:
- C 和 C++ 中开关语句的案例标签的常量值,但显示不同的行为
- 如何正确指定 goto 语句的标签?
- 使用g++静态初始化带有命名标签的嵌套C++结构
- 通过水平滚动条更改标签
- 从 QFontDatabase 设置 QFont 将所有标签设置为等宽字体?Qt C++
- 在C++中存储要输入的标签列表
- 如何在等效列表中查找最小的连接标签
- 标签检测鼠标单击 c++
- 无法将行编辑中的文本打印到 Qt C++ 中的标签
- 如何根据C++中的标签运行特定函数?
- C++ Expat 仅打印元素的第一个字母和标签中的数据
- 默认标签显然在 switch 语句中不起作用
- 在 gcc/clang (C++) 中获取函数范围之外的标签地址
- 在"printf"中使用标签"h"或"hh"是否涉及未定义的
- GTK 3 C++按钮中带有标签的图标
- 如何使QLineSeries/QXYSeries仅显示一个点标签
- SFINAE和标签调度之间的差异
- 如何在主窗口标签的对话框中显示QLineEdit的输入
- Qt - 将空指针(原始数据)转换为 QImage 并将其显示在标签上
- 我可以给出不同的行为来提升::p roto::标签类型吗?