c++使用 int 和 char* 重载构造函数

发布于 2024-10-28 08:12:26 字数 287 浏览 5 评论 0原文

我尝试使用 intchar * 重载构造函数。然后使用 0 进行调用时存在歧义。有没有解决方法/解决方案?

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

问题出在0线上:

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

感谢您的回答。

I try to overload constructor with int and char *. Then there is ambiguity in call with 0. Is there any workaround/solution for this?

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

The problem is on the line with 0:

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

Thanks for answering.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

意中人 2024-11-04 08:12:26

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

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

Make one of the constructors explicit. It will then only be used when passed type exactly matches.

CBigInt (unsigned int);
explicit CBigInt (const char *);
ヤ经典坏疍 2024-11-04 08:12:26

您可以使用“explicit”关键字:

explicit CBigInt(const char *);

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

You could use the "explicit" keyword:

explicit CBigInt(const char *);

Using this, you must explicitly cast the argument to a const char *, otherwise CBigInt(unsigned) will be executed.

榆西 2024-11-04 08:12:26

“显式”方法是有效的,但对于将来支持开发人员来说可能不直观。
对于这样的情况,在我之前从事的项目中,我们使用静态工厂方法。
我们将有一个私有的默认构造函数并显式初始化静态工厂中的成员。类似于:

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; 
};

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

The 'explicit' approach works, but may not be intuitive for supporting developers in the future.
For cases like these, in previous projects I've worked on, we used static factory methods.
We would have a private default constructor and explicitly initialize the members in the static factories. Something like:

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; 
};

This approach removes any ambiguity not only for the compiler, but also for the one who will support your code later.

不疑不惑不回忆 2024-11-04 08:12:26

在这种情况下,我还建议使用显式构造函数,因为我认为任意字符串(构造函数采用的)不会对数字进行建模(您的 CBigInt 类模型) 。这种情况正是 explicit 的设计目的。

但是,这对于使用直接初始化的情况不起作用

struct A {
  CBigInt n;
  A():n(0) { } // ambiguity again
};

。一般来说,不应该使用显式来解决内部歧义。它应该仅用于禁止从一种类型到另一种类型的转换,而不是比显式构造函数更喜欢另一个构造函数。事实上,新的 C++0x 统一初始化将不会忽略复制初始化上下文中的显式构造函数:

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 *);

In this case I would also recommend an explicit constructor, because I think that an arbitrary string (which your constructor takes) does not model a number (which your CBigInt class models). Such cases are what explicit was designed for.

However, this will not work for cases where direct initialization is used

struct A {
  CBigInt n;
  A():n(0) { } // ambiguity again
};

In general, explicit should not be used to resolve internal ambiguities. It should merely be used to forbid the conversion from one type to the other, but not to prefer another constructor over the explicit constructor. In fact, the new C++0x uniform initializations will not ignore explicit constructors in a copy initialization context:

CBigInt f() {
  return { 0 }; // still ambiguous
}

CBigInt b = { 0 }; // still ambiguous

The rules for uniform initialization is: Both constructors are considered, but if an explicit constructor is chosen, initialization is ill-formed.

The literal 0 is an int. Assuming you want to be able to accept all integer types, you need to at least add an int taking constructor. You don't need to add overloads for integer types smaller than int, because those types prefer int over other integer conversions or pointers. Assuming you have an int overload you also need to add overloads for the remaining integer types and, if available and you use it, long long and unsigned long long. Ambiguities will then not arise anymore:

CBigInt (int);
CBigInt (unsigned int);
CBigInt (long);
CBigInt (unsigned long);
// CBigInt (long long);
// CBigInt (unsigned long long);
explicit CBigInt (const char *);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文