【问题标题】:c++ overload constructor with int and char*c++ 用 int 和 char* 重载构造函数
【发布时间】:2011-03-31 11:28:50
【问题描述】:

我尝试使用intchar * 重载构造函数。然后在与0 的通话中存在歧义。是否有任何解决方法/解决方案?

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

问题出在0线上:

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

感谢您的回答。

【问题讨论】:

  • 我假设你已经超载了operator *=?这让我一时糊涂。
  • 如果你使用std::string,它就不会发生。

标签: c++ constructor overloading ambiguity


【解决方案1】:

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

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

【讨论】:

  • 更好,让两者都明确:)
  • @Matthieu M:不,那么他必须写a *= CBigInt(0u),考虑到OP显示的使用场景,我认为默认情况下他希望积分转换为CBigInt
  • 是的,这行得通,但我忘了说,我也希望能够从 chars * 编写转换,例如:a *= "131"
  • 你可以使 op *= 像这样(除了使用 Foo 的那个)template<typename T> CBigInt & operator*=(T const & V) { return *this *= CBigInt(V); } - 与一些显式构造函数一起应该可以正常工作。
【解决方案2】:

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

explicit CBigInt(const char *);

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      在这种情况下,我还建议使用 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
      

      统一初始化的规则是:考虑两个构造函数,但如果选择显式构造函数,则初始化是非良构的。

      文字0int。假设您希望能够接受所有整数类型,您至少需要添加一个 int 接受构造函数。您不需要为小于int 的整数类型添加重载,因为这些类型比其他整数转换或指针更喜欢int。假设你有一个int 重载,你还需要为剩余的整数类型添加重载,如果可用并且你使用它,long longunsigned long long。这样就不会再出现歧义了:

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

      【讨论】:

      • 澄清:添加 CBigInt::CBigInt(int) 消除 OP 示例中的歧义。
      猜你喜欢
      • 2018-05-30
      • 2021-11-29
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多