2011-11-24 56 views
8

我必须写两个默认参数的构造函数。如何跳过默认参数C++?

func(int arg1 , char* arg2 = "arg2", int arg3 = 1) //example 

我提供在构造函数被调用的场景和值是给arg1arg2arg3预计将使用默认值。然后另一个对象被实例化并且给定值为arg1arg3,并且预期将使用arg2的默认值。 现在的问题是,你“无法跳过”默认参数是我正在从文本和在线阅读。它的意思是命令默认的参数从超负荷的角度来看,但是场景有一个默认参数,而另一个参数不是。这个问题的提示告诉我重新排序参数/参数。但是,我所做的重新排序量似乎无法解决此问题。

此外,重载的构造函数不能使用。这必须由一个构造函数完成。

那么如何做到这一点?我难倒和去有点疯狂了这个:(

+6

您不能在C++中使用单个函数定义来完成此操作。鉴于任何其他解决方案违反了你所拥有的奇怪限制,你想要的是不可能的。也许你可以使用不同的语言。 –

+1

正在做作业吗? – xmoex

+0

你不能使用对象的'vector'吗?这样你就可以传递你想要的东西,并根据'null'条目对没有传递的东西进行排序。 – MoonKnight

回答

6

而且,重载的构造函数不能使用。这必须通过一个构造函数来完成。

我能想到的唯一原因这个要求是可选的参数具有相同的类型。在这种情况下,你就完蛋了,你会想看看到named constructor和/或named parameter成语。

否则,只定义了额外的构造函数。这可能会涉及一些重复和默认值。

Foo(int arg1 , char const *arg2 = "arg2", int arg3 = 1) 
{ 
    construct(arg1, arg2, arg3); 
} 

Foo(int arg1, int arg3) 
{ 
    construct(arg1, "arg2", arg3); 
} 
+1

这些是一些非常好的成语,感谢分享链接。关于堆栈溢出的一个很棒的事情是,你可以随机地细读线程并学习一些很酷的东西:) +1 –

0

特殊的限制,只能有一个构造函数。这是我能想到的最接近的:

#include <iostream> 

// cheap and cheerful Boost.Variant 
struct StringOrInt { 
    char *s; 
    int i; 
    bool is_string; 
    StringOrInt(char *s) : s(s), i(0), is_string(true) {} 
    StringOrInt(int i) : s(0), i(i), is_string(false) {} 
    bool isInt() { return !is_string; } 
    int asInt() { return i; } 
    char *asString() { return s; } 
}; 

struct Foo { 
    int m1; 
    char *m2; 
    int m3; 
    Foo(int arg1, StringOrInt arg2 = "arg2", int arg3 = 1) : m1(arg1) { 
     if (arg2.isInt()) { 
      arg3 = arg2.asInt(); 
      arg2 = "arg2"; 
     } 
     m2 = arg2.asString(); 
     m3 = arg3; 
    } 
    void print() { 
     std::cout << m1 << " " << m2 << " " << m3 << "\n"; 
    } 
}; 

int main() { 
    Foo(1, "HelloWorld").print(); 
    Foo(1, 2).print(); 
} 

注意与GCC这会产生警告,因为从一个字符串到非const char*转换已被弃用,不明智的。但这是你要求的,并修复它,以便char*参数和数据成员是const char*很容易。

一个显着的弱点是,这并不能阻止你写Foo(1,2,3)。要在编译时检查,我认为你需要多个构造函数。要在运行时检查它,可以将第三个参数设置为另一个类,其中Default是仅用于此目的的类型,仅支持一个用作arg3的默认值的值。那么,如果arg2.isInt()为真,则检查arg3.isInt()是否为假,如果不是则拒绝logic_error

0

如果您在第二个参数没有值的情况下允许传递空的C字符串,则可以使用助手函子来检查arg2,如果它为空则返回默认值。事情是这样的:

#define DEFAULT_ARG "arg2" 

struct helper_class { 
    char* operator()(char* arg) 
    { 
     if (*arg) return arg; else return DEFAULT_ARG; 
    } 
} helper; 

class func { 
    public: 
    func(int arg1 , char* arg2 = "arg2", int arg3 = 1) {} 
}; 

int main() 
{ 
    func f1(42, helper(""), 9001); // default 2nd argument 
    func f2(42, helper("Its over 9000!")); 
} 

不漂亮,我知道......

0

现在你可以使用std::bind做这种手术或C++十七分之十四你可以使用lambda函数,完成一样。