在C ++中编译时强制执行函数调用

时间:2014-09-11 06:49:19

标签: c++ named-parameters

C ++中是否有办法在编译时强制执行函数调用,以便允许此调用:

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

但是这个将无法编译:

obj.reset().setParam1(10);

我想避免在一个函数中设置所有参数,因为设置太多了;所以我更喜欢使用与命名参数idiom类似的东西。

编辑:替代语法可能是:

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

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

3 个答案:

答案 0 :(得分:2)

由于在编译时必须存在所需的行为,因此需要在类型系统中实现。根据我的理解,这在C ++中是不可能的 - 命名参数idiom依赖于具有相同返回类型的setter函数(即被调用的对象的类型),因此无法阻止对某些方法的调用。

答案 1 :(得分:2)

我将举例说明使用您提供的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 :(得分: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"));
}