2014-09-11 1 views
4

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

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

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

obj.reset().setParam1(10); 

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

EDIT: Альтернативный синтаксис может быть:

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

или

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

Я действительно не думаю, что вы можете с ним что-либо сделать. С помощью некоторой магии шаблонов, возможно, вы можете добиться подобного поведения, но с другим синтаксисом. Можете ли вы рассказать мне, зачем вам это нужно? Возможно, мы сможем найти решение с более умным дизайном. : P – Melkon

+0

@Melkon Цель состоит в том, чтобы заставить пользователя класса установить ВСЕ требуемые параметры, не заставляя его использовать одну функцию setter с десятком аргументов. – jackhab

+1

Ну, я точно не понимаю, в чем смысл этого синтаксиса. Я думал, что вы хотите что-то вроде 5 параметров, но обязательно указать как минимум 2 из них. На самом деле функции цепочки медленнее, и их труднее читать, по сравнению с одной функцией, которая устанавливает все параметры. Вы также можете сохранить все входные параметры в структуре и определить одну функцию, которая нуждается в этой структуре. Почему этот синтаксис важен? – Melkon

ответ

0

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

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")); 
} 
2

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

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 
} 
+0

Интересное решение, но определение типа обеспечивает фиксированную последовательность вызовов setter. – Codor

+0

Или несколько «фиксированных последовательностей вызовов сеттера», если требуется больше параметров и используются больше классов. Эта концепция используется некоторыми библиотеками для обеспечения простого в использовании API-интерфейса с возможностью соединения. – mostruash

+0

В моем случае obj.setParam2 (10) запрещен. Нужно называть ВСЕ сеттеры. Порядок не важен. Я думал о создании цепочки obj1-obj2-objn, а затем менял функции сброса для получения аргумента objn: obj.reset (setParam1 (10) .setParam (20)), но тогда как бы ссылка obj попала в функцию setParam1()? Я немного запутался. – jackhab

 Смежные вопросы

  • Нет связанных вопросов^_^