布尔表达式的构造函数,而不是结果

时间:2013-07-26 11:20:27

标签: c++ binding conditional-statements state-machine

我创建了一个名为binding_condition的模板类,以便我可以将条件的排列抽象到单个对象。目前它适用于传递lambda和需要检查的任何变量,但我发现lambda是误导性的,因为它需要捕获我引用的变量。

例如:

bool someVal = true;
int h = 10;
double p = 99.8;
char c = 'C';

binding_condition<bool> bc(
    [] (bool b) 
{ return b; }, 
someVal);

binding_condition<bool, int> bc2(
    [] (bool b, int i) 
{ return b && (i > 9); }, 
someVal, h);

binding_condition<bool, int, double> bc3(
    [] (bool b, int i, double d) 
{ return b && (i > 9) && (d < 100); }, 
someVal, h, p);

binding_condition<bool, int, double, char> bc4(
    [] (bool b, int i, double d, char c) 
{ return b && (i > 9) && (d < 100) && c == 'C'; }, 
someVal, h, p, c);

这允许我将一些复杂的条件抽象为一个名称:

if (ThisComplexCondition) ...
else if (ThisOtherComplexCondition ...
...

但是我想知道是否有方法,无论是使用表达式模板还是其他方法,都允许这样的语法:

 binding_condition<bool, int, double> ComplexCondition = myClass.isTrue() && someThing.id < 100 && someDouble > 30.2;

我意识到上面的表达并不是特别有创意,但请考虑下一个:

// analyzing chords in music to roman numeral notation, detect modulations, etc

// isChordRelatedToKey (the chord can be made from the current key

// isNeopolitan (the chord is a bii6 of the current key
   // is major
   // letter() is II/ii (ie C# major in C major is not a neapolitan, but Db major is)

// isSecondaryDominant 
   // chord is major
   // chord is dominant of next chord (requires a new temporary key of next chord

// isSecondaryDiminished
   // chord is diminished, and is the viio of the next chord
// all other forms of secondary, which means a ii/V in C major is A minor, which is also the vi of the key, and the iii/IV is also A minor

// nested secondary chords ie I - V - V/V - vii/V/V (C major, G major, D major, C# diminished)  

// isModulation
   // the current string of chords is not related to the current Key anymore

我想实现某种状态机,将这些限制打包到对象中,并简单地检查:

if (isModulation) ...
if (isSecondary) ... // recursive
if (isChordNoRelation) ... // some chord that makes no sense from previous string

但宝贝一步一步走。现在我只想知道我是否可以分配和存储表达式,以及该表达式中引用的任何变量/函数。

这可能吗?

1 个答案:

答案 0 :(得分:0)

lambda闭包有什么问题,捕获变量?您不需要将它们作为参数传递。在第一个示例中,您可以执行此操作:

bool someVal = true;
int h = 10;
double p = 99.8;
char c = 'C';

auto bc4 = [&](){return someVal && (h > 9) && (p < 100) && c == 'C';};

//later:
if(bc4()) 
{
  /*...*/ 
}

和第二个例子:

auto ComplexCondition = [&]() { return myClass.isTrue() && someThing.id < 100 && someDouble > 30.2;};

lambda表达式通过引用捕获所提到的变量的prodice闭包,因此在调用闭包operator()时会计算值:

bool someVal = true;
int h = 10;
double p = 99.8;
char c = 'C';

auto bc4 = [&](){return someVal && (h > 9) && (p < 100) && c == 'C';};

if(bc4()) //gives true
{ /* ... */ }

p *= 2;
if (bc4()) {} //gives false, since p > 100