【问题标题】:Ambiguous call to overloaded integer constructor对重载整数构造函数的模糊调用
【发布时间】:2016-01-22 21:02:26
【问题描述】:

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

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

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

整数字面量的类型是对应列表的第一个 在表6中可以表示其值。

表 6 在这里

int
long int
long long int

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

&lt;0, numeric_limits&lt;int&gt;::max()&gt;int

---> 调用 BigUnsigned(int)

(numeric_limits&lt;int&gt;::max(), numeric_limits&lt;long int&gt;::max()&gt;long int

--->模棱两可

(numeric_limits&lt;long int&gt;::max(), too big literal)long long int

--->模棱两可

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

This question on integer promotioninteger conversion 可能有用。不过,我仍然不知道其中哪一个适用于我的情况。

【问题讨论】:

  • 您需要int 构造函数吗? BigUnsigned(unsigned long long value); 不是涵盖了你想要的一切吗?
  • @NathanOliver 似乎确实如此。但是,分配迫使我实现这两个构造函数,可能是为了解决这类问题:)。 int 参数应与位级别上的 unsigned long long 完全相同。
  • 显式好,隐式不好。添加一个 tie-breaker 第一个参数,如果可能的话,使用一些自我描述的名称。如果无法设计一个合理的名称,那么这个设计就是不好的,必须扔到最近的火上。
  • @Cheersandhth.-Alf 我不允许更改公共界面。
  • 投票关闭,因为不清楚您的要求。

标签: c++ c++11 integer type-conversion integer-promotion


【解决方案1】:

这里的一个基本问题是十进制文字永远不会被推导出为无符号类型。因此,一个太大而无法放入 int 的十进制文字最终需要在一种情况下进行有符号->无符号转换,而在另一种情况下需要进行 long->int 转换。这两个都被归类为“积分转换”,因此都不是“更好”的转换,并且重载是模棱两可的。

关于在不显式转换参数或添加更多构造函数的情况下处理此问题的可能方法,我可以看到一些。

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

BigUnsigned a(5000000000U); // unambiguous

另一个(也仅适用于文字)是使用十六进制或八进制文字,(根据问题中未引用的表 6 的一部分)可以推断为带符号的 或 无符号。不过,这只是部分修复——它仅适用于将推断为无符号的值。对于一个典型的 32 位 int、32 位 long 和 64 位 long long 的系统,我相信它会是这样的:

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

对于使用过较小类型的人来说,从 unsigned long 到 unsigned long long 的转换最初看起来像是升级而不是转换,这将使其更可取。事实上,如果(例如)所涉及的类型是unsigned shortunsigned int,那将是完全正确的——但只有转换等级低于int 的类型才给予特殊偏好(基本上转换为:小于 int 的类型)。

这样就解决了一个数字范围的问题,但前提是它们是文字,并且只有它们落入一个特定(尽管相当大)的范围内。

对于更一般的情况,唯一真正的解决方法是更改​​接口。要么删除int 的重载,要么添加更多的ctor 重载,特别是unsignedlong long。这些可以像int 的现有构造函数一样委派构造函数,如果您决定完全需要它们(但最好只拥有unsigned long long 的构造函数并完成它)。

【讨论】:

  • unsigned shortunsigned int 只是在int 不能代表unsigned short 的所有值的情况下进行的提升。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2011-12-12
  • 2014-09-05
相关资源
最近更新 更多