именованные параметры — принудительное выполнение вызовов функций во время компиляции в переполнении стека

Есть ли способ в C ++ для обеспечения вызовов функций во время компиляции таким образом, что этот вызов будет разрешен:

obj.reset().setParam1(10).setParam2(20);

но этот не удастся скомпилировать:

obj.reset().setParam1(10);

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

РЕДАКТИРОВАТЬ: Альтернативный синтаксис может быть:

obj.reset(setParam1(10), setParam2(20));

или же

obj.reset(setParam1(10).setParam2(20));

4

Решение

Поскольку желаемое поведение должно присутствовать во время компиляции, оно должно быть реализовано в системе типов. Насколько я понимаю, это невозможно в C ++ — идиома именованных параметров опирается на функции-установщики, имеющие одинаковый возвращаемый тип (а именно тип вызываемого объекта), поэтому вызовы определенных методов не могут быть предотвращены.

2

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

Я приведу вам пример того, как вы делаете это с двумя указанными вами параметрами. Если вам нужно больше, нужно больше работать. Если иерархия требований между параметрами становится слишком сложной, вам может быть сложно структурировать ваши классы, но здесь это так:

class Obj {
Obj2 setParam2(int v);
}

class Obj2: public Obj {
Obj2 setParam1(int v);
}

int main() {
Obj obj;
obj.setParam2(10); // possible
obj.setParam2(10).setParam1(20); // possible
obj.setParam1(20); // not possible
obj.setParam1(20).setParam2(10); // unfortunately not possible

// Edit: one more limitation- consecutive calls are not possible,
// you must chain
obj.setParam2(20);
obj.setParam1(10); // problem
}
2

Лучшее, что я мог сделать, чтобы предоставить оба именованных параметра и обеспечить инициализацию всех их, это это.

template<typename T>
struct Setter
{
Setter(const T &param) : ref(param) {}
const T &ref;
};typedef Setter<int> Param1;
typedef Setter<std::string> Param2;struct CObj
{
void reset(const Param1 &A, const Param2 &B) {
setParam1(A.ref); setParam2(B.ref); }

void setParam1(int i) { param1 = i; }
void setParam2(const std::string &i) { param2 = i; }

int param1;
std::string param2;
};int main()
{
CObj o;
o.reset(Param1(10), Param2("hehe"));
}
0
По вопросам рекламы [email protected]