Expression Template---表达式模板
- What is expression template?
Expression templates is a C++ template metaprogramming technique in which templates are used to represent part of an expression. Typically, the template itself represents a particular type of operation, while the parameters represent the operands to which the
operation applies. The expression template can then be evaluated at a later time, or passed to a function. [1]
- How can it help you?
1. To create a domain-specific embedded language (DSEL) in C++2. To support lazy evaluation of C++ expressions (e.g., mathematical expressions), which can be executed much later in the program from the point of their definition.
3. To pass an expression -- not the result of the expression -- as a parameter to a function. [2]
- Principle:
Expression templates use the Recursive Type Composition idiom. Recursive type composition uses instances of class templates that contain other instances of the same template as member variables. Multiple repetitive instantiation of the same template gives rise
to an abstract syntax tree (AST) of types. Recursive type composition has been used to create linear Type lists as well as binary expression trees. [2]
- Use case:
/**
@file "expression_template.hpp"
@brief Expression template
@author C.Zhou, Eric
@date 2012.3
*/
#if !defined(IDEA_TEST_EXPRESSION_TEMPLATE_HPP)
#define IDEA_TEST_EXPRESSION_TEMPLATE_HPP
namespace ExprTemplate
{
//operand, represent a variable
struct var
{
double operator() (double d) const
{
return d;
}
};
//operand, represent a constant
struct constant
{
explicit constant(double d) : m_d(d){}
double operator() (double) const
{
return m_d;
}
double m_d;
};
//expression, this makes the binary operation can be lazily evaluated.
template <typename Var0, typename Var1, typename OP>
struct binary_expression
{
binary_expression(const Var0& var0, const Var1& var1) : m_var0(var0), m_var1(var1)
{}
double operator() (double d) const
{
return OP::apply(m_var0(d), m_var1(d));
}
Var0 m_var0;
Var1 m_var1;
};
//operation, add
struct add
{
static double apply(double d0, double d1) {return d0 + d1;}
};
//expression in form of template
template <typename Expr>
struct expression
{
explicit expression(const Expr& expr) : m_expr(expr){}
double operator() (double d) const
{
return m_expr(d);
}
Expr m_expr;
};
}//ExprTemplate
#endif//IDEA_TEST_EXPRESSION_TEMPLATE_HPP
/**
@file "expression_template.cpp"
@brief Expression template
@author C.Zhou, Eric
@date 2012.3
*/
#include "expression_template.hpp"
#include <vector>
#include <iostream>
namespace ExprTemplateTest
{
template <typename Iter, typename Func>
void evaluate(Iter begin, Iter end, Func func)
{
for(Iter iter = begin; iter != end; ++iter)
std::cout << func(*iter) <<std::endl;
}
void test()
{
using namespace ExprTemplate;
typedef expression<var> var_expr_t;
typedef expression<constant> const_expr_t;
typedef binary_expression<var_expr_t, const_expr_t, add> var_const_adder_t;
typedef expression<var_const_adder_t> my_adder_t;
var my_var;
var_expr_t var_x(my_var);
const_expr_t const_x(constant(4.8));
var_const_adder_t v_c_adder(var_x, const_x);
my_adder_t expr(v_c_adder);
std::vector<double> data;
data.push_back(1.2);
data.push_back(10.8);
evaluate(data.begin(), data.end(), expr);
}
}//ExprTemplateTest
/**
@file "main.cpp"
@brief Expression template
@author C.Zhou, Eric
@date 2012.3
*/
int _tmain(int argc, _TCHAR* argv[])
{
ExprTemplateTest::test();
return 0;
}
Ref:
[1]: http://en.wikipedia.org/wiki/Expression_templates
[2]: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Expression-template
Dig:
http://blog.csdn.net/ralph623/article/details/505190
http://www.angelikalanger.com/Articles/Cuj/ExpressionTemplates/ExpressionTemplates.htm