我正在尝试将惰性评估引入现有的代码项目。项目核心基本上由使用自定义类型的大量计算组成(它的作用类似于 double,但在后台执行额外的工作)。
我们的目标是使用 boost proto 引入惰性求值概念,以优化现有表达式。
限制:
- 无法触及现有的计算
- 使用的类型由 typedef 定义,因此可以替换类型本身
我们试图实现一个简单的概念证明,但没有管理代码以使其按预期运行。这是我们到目前为止得到的:
#include <boost/proto/proto.hpp>
#include <complex>
#include <iostream>
using namespace std;
using namespace boost;
using namespace boost::proto;
// The custom implemented Type
typedef std::complex<double> my_type;
// The Basic expression wrapper
template< typename Expr = proto::terminal< my_type >::type >
struct MyDoubleExpr
: proto::extends< Expr, MyDoubleExpr< Expr >, proto::default_domain >
{
typedef
proto::extends< Expr, MyDoubleExpr< Expr >, proto::default_domain >
base_type;
MyDoubleExpr( Expr const &expr = Expr() )
: base_type( expr )
{}
// Overloading of all Constructors supported by the custom type
typedef typename proto::terminal< my_type >::type expr_type;
MyDoubleExpr( double const &d)
: base_type( expr_type::make(my_type(d)))
{}
// Lazy assignment is desired
BOOST_PROTO_EXTENDS_USING_ASSIGN(MyDoubleExpr)
};
// unintrusively replace the existing type with
// the expression template
typedef MyDoubleExpr<> replaced_type;
int main() {
replaced_type a = 2.0, b = 1.5;
proto::default_context ctx;
// The replaced type is created as template specialisation
// proto::terminal< my_type >::type -> cannot store expressions
replaced_type c;
c = (a + b) * 2.0;
std::cout << "c: " << proto::eval(c,ctx) << endl << endl;
proto::display_expr(c);
// Initialisation does not work directly ?
//replaced_type d = a+b;
// using auto works fine, so the expression basically works
auto e = (a + b) * 2.0;
std::cout << "e: " << proto::eval(e,ctx) << endl;
proto::display_expr(e);
getchar();
return 0;
}
我们的主要问题是我们无法定义一种既适用于文字又适用于表达式的类型。在这个例子中,c 是一个 proto::terminal 类型的表达式并且忽略了表达式的赋值。使用 auto 存储表达式时,它工作正常。此外,直接初始化是不可能的。
如果我正确理解我们的问题,我们将需要两种不同类型的表达式和文字,这是不可能的,因为我们只能更改现有类型。
我们还研究了其他选项,例如使用 BOOST_PROTO_DEFINE_OPERATORS(...) 使我们的自定义类型成为非侵入式终端,但也不能进行延迟分配。
所以,我们的问题是我们是否可以实现我们想要的,或者我们是否必须更改现有代码以引入惰性评估?
感谢您的帮助,马蒂亚斯enter code here