0

我创建了一个名为 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

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

这可能吗?

4

1 回答 1

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 表达式产生通过引用捕获上述变量的闭包,因此在调用闭包 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
于 2013-07-26T12:37:26.420 回答