繁体   English   中英

对重载的 integer 构造函数的模糊调用

[英]Ambiguous call to overloaded integer constructor

我将提供这两个构造函数。

BigUnsigned(int value)
    :BigUnsigned(static_cast<unsigned long long>(value)){
}
BigUnsigned(unsigned long long value);

问题是某些参数值的调用不明确。 根据这个答案,指的是 C++11 标准,

integer 文字的类型是表 6 中可以表示其值的相应列表中的第一个。

表 6 在这里

int
long int
long long int

因此,在我的情况下,构造函数参数的类型(整数文字)如果它属于范围......

<0, numeric_limits<int>::max()>int

---> 调用 BigUnsigned(int)

(numeric_limits<int>::max(), numeric_limits<long int>::max()>long int

---> 模棱两可

(numeric_limits<long int>::max(), too big literal) is long long int

---> 模棱两可

如何在不声明更多构造函数或显式类型转换参数的情况下解决歧义?

这个关于integer promotioninteger conversion的问题可能很有用。 不过,我仍然不知道其中哪一个适用于我的情况。

这里的一个基本问题是十进制文字永远不会被推断为无符号类型。 因此,一个十分小的文字太大而不适合int最终需要在一种情况下进行signed-> unsigned转换,而在另一种情况下需要long-> int转换。 这两个都被归类为“积分转换”,因此两者都不被认为是“更好”的转换,并且过载是模糊的。

至于在没有明确地转换参数或添加更多构造函数的情况下处理此问题的可能方法,我可以看到一对。

至少对于文字,您可以添加一个后缀,指定文字的类型是无符号的:

BigUnsigned a(5000000000U); // unambiguous

另一个(也仅适用于文字)将使用十六进制或八进制文字,(根据表6中未引用的部分)可以推导为有符号无符号。 这只是一个部分修复 - 它只适用于推导为无符号的值。 对于具有32位int,32位长和64位长的典型系统,我相信它会像这样出现:

在此输入图像描述

因此,对于一个足够大的参数,它将不适合带符号的long long,这给出了一个明确的调用,其中十进制常量仍然是不明确的。

对于那些使用较小类型的人来说,最初看起来似乎从无符号长整数到无符号长整数的转换可以作为促销而不是转换,这将使其更受欢迎。 事实上,如果(例如)所涉及的类型是unsigned shortunsigned int ,那将完全正确 - 但是特殊偏好仅针对转换等级小于int类型(基本上转换为:较小的类型)比int)。

所以这解决了一个数字范围的问题,但只有当它们是文字时,并且只有当它们属于一个特定的(尽管是非常大的)范围时。

对于更一般的情况,唯一真正的解决方法是更改​​界面。 删除int的重载,或者添加一些ctor重载,特别是对于unsignedlong long 这些可以委托构造就像现有的int ,如果你决定你需要他们在所有(但它可能是更好的只是有一个unsigned long long ,并用它做)。

我有同样的问题。 还有一些大整数类。 然而,纯文字的解决方案对我不起作用,因为我需要在彼此之间转换完全不同类型的(大)整数。 我试图避免构造函数的过度实现。 我解决了这样的问题:

  template <std::same_as<MyOtherBigInt> T>
  explicit constexpr MyBigInt(T pValue) noexcept;

这会阻止特殊的 MyOtherBigInt-Constructor 与任何其他 integer 一起调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM