Конструктор для логического выражения, а не результат

Я создал шаблонный класс с именем binding_condition, чтобы можно было абстрагировать условия для одного объекта. В настоящее время она работает с передачей лямбды и любых переменных, которые необходимо проверить, но я считаю, что лямбда вводит в заблуждение, поскольку она должна захватывать переменные, на которые я ссылаюсь.

например:

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

Но ребенок шагает за один раз. Прямо сейчас я просто хочу знать, могу ли я назначить и сохранить выражение с любыми переменными / функциями, на которые есть ссылки в этом выражении.

Это возможно?

0

Решение

Что не так с лямбда-замыканиями, захватом переменных? Вам не нужно передавать их как параметры. В вашем первом примере вы можете сделать это:

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;};

Замыкания с использованием лямбда-выражений, которые захватывают упомянутые переменные по ссылке, поэтому значения оцениваются, когда вызывается оператор замыкания ():

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
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]