5

我尝试用intand重载构造函数char *。然后与 通话有歧义0。有什么解决方法/解决方案吗?

CBigInt (unsigned int);
CBigInt (const char *);

问题在于0

CBigInt a;
// some more code
 a *= 0; 

谢谢回答。

4

4 回答 4

10

使构造函数之一显式。只有当传递的类型完全匹配时才会使用它。

CBigInt (unsigned int);
explicit CBigInt (const char *);
于 2011-03-31T11:34:16.753 回答
6

您可以使用“显式”关键字:

explicit CBigInt(const char *);

使用它,您必须将参数显式转换为 const char *,否则将执行 CBigInt(unsigned)。

于 2011-03-31T11:34:04.807 回答
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; 
};

这种方法不仅消除了编译器的歧义,也消除了稍后将支持您的代码的人的歧义。

于 2011-03-31T12:07:51.473 回答
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 *);
于 2011-03-31T14:38:29.190 回答