我尝试使用int
和char *
重载构造函数。然后与0
通话时含糊不清。有没有解决方法/解决方案呢?
CBigInt (unsigned int);
CBigInt (const char *);
问题在于0
:
CBigInt a;
// some more code
a *= 0;
感谢您的回答。
答案 0 :(得分:10)
使其中一个构造函数显式化。它只会在传递类型完全匹配时使用。
CBigInt (unsigned int);
explicit CBigInt (const char *);
答案 1 :(得分:6)
您可以使用" explicit"关键字:
explicit CBigInt(const char *);
使用此方法,必须将参数显式转换为const char *,否则将执行CBigInt(unsigned)。
答案 2 :(得分:2)
“显式”方法有效,但未来支持开发人员可能不直观。 对于这样的情况,在我以前的项目中,我们使用了静态工厂方法。 我们将有一个私有默认构造函数,并显式初始化静态工厂中的成员。类似的东西:
class CBigInt {
public:
...
static CBigInt fromUInt(unsigned int i) {
CBigInt result;
result.value=i;
return result;
}
static CBigInt fromCharPtr(const char* c) {
CBigInt result;
result.value=parse(c);
return result;
}
...
private:
CBigInt () {}
/*some internal type here*/ value;
};
这种方法不仅消除了编译器的歧义,也消除了以后支持代码的人的歧义。
答案 3 :(得分:1)
在这种情况下,我还建议使用explicit
构造函数,因为我认为任意字符串(构造函数所采用的)不会对数字建模(您的CBigInt
类模型)。这种情况是explicit
的目的。
但是,这对于使用直接初始化的情况不起作用
struct A {
CBigInt n;
A():n(0) { } // ambiguity again
};
通常,explicit
不应用于解决内部歧义。它应该仅用于禁止从一种类型到另一种类型的转换,而不是优先于explicit
构造函数上的另一个构造函数。实际上,新的C ++ 0x统一初始化将在复制初始化上下文中不忽略explicit
构造函数:
CBigInt f() {
return { 0 }; // still ambiguous
}
CBigInt b = { 0 }; // still ambiguous
统一初始化的规则是:两个构造函数都被考虑,但如果选择了显式构造函数,则初始化是错误的。
文字0
是int
。假设您希望能够接受所有整数类型,则至少需要添加一个int
构造函数。您不需要为小于int
的整数类型添加重载,因为这些类型比其他整数转换或指针更喜欢int
。假设您有int
重载,您还需要为剩余的整数类型添加重载,如果可用,则使用long long
和unsigned long long
。然后不再出现歧义:
CBigInt (int);
CBigInt (unsigned int);
CBigInt (long);
CBigInt (unsigned long);
// CBigInt (long long);
// CBigInt (unsigned long long);
explicit CBigInt (const char *);