【问题标题】:Overload resolution works on functions, but not with implicit constructor parameters重载解析适用于函数,但不适用于隐式构造函数参数
【发布时间】:2021-02-24 08:53:34
【问题描述】:

此代码显示了__int32bool 类型的基本包装类。我的意图是使用方法和自定义运算符等扩展基本类型。

每个类都有一个隐式构造函数,允许将__int32 隐式分配给Int32 类型。这很好用,直到有一个函数重载接受 both Int32Boolean

虽然具有重载 __int32bool 的函数可以编译和工作,但具有重载类的函数会导致对重载函数的模糊调用

我的问题:有没有办法正确解决这个问题,这样我就可以为基本类型实现包装类,而不会出现重载解决问题,也不需要调用者进行显式强制转换?

class Boolean
{
private:
    bool _Value = false;
public:
    Boolean(bool value)
    {
        _Value = value;
    }
};

class Int32
{
private:
    __int32 _Value = 0;
public:
    Int32(__int32 value)
    {
        _Value = value;
    }
};

void AmbiguousFunc(const Int32 &x) { }
void AmbiguousFunc(const Boolean &x) { }

void NotAmbiguous(__int32 x) { }
void NotAmbiguous(bool x) { }

int main(int argc, char *argv[])
{
    AmbiguousFunc(123);         // Ambiguous calls to overloaded function
    AmbiguousFunc((Int32)123);  // works
    NotAmbiguous(123);

    return 0;
}

【问题讨论】:

  • 除了问题之外的所有内容:根据 C++ 标准,实现保留带有下划线后跟大写字母的标识符。包含两个后续下划线的标识符由实现根据 C 标准(在 C++ 标准中引用)保留。而不是使用 hte 实现提供的__int32 类型,您应该改为使用#include <cstdint> 并使用std::int32_t(或更便携,类似std::int_least32_t)。或者,只需使用普通的int。您还应该在构造函数成员初始化列表中初始化成员。
  • 一般情况下,int != __int32

标签: c++ implicit-conversion overload-resolution


【解决方案1】:

问题是,给定AmbiguousFunc(123);123可以先转换成bool(标准转换),再转换成Boolean(自定义转换);与用户自定义的123Int32的转换排名相同,那么AmbiguousFunc(const Int32 &)AmbiguousFunc(const Boolean &)之间的调用是不明确的。

您可以将构造函数更改为模板,并将它们限制为仅接受适当的类型。

class Boolean
{
private:
    bool _Value = false;
public:
    // accept bools only; no __int32s
    template <typename T, std::enable_if_t<std::is_same_v<T, bool>>* = nullptr>
    Boolean(T value)
    {
        _Value = value;
    }
};

class Int32
{
private:
    __int32 _Value = 0;
public:
    // accept __int32s only; no bools
    template <typename T, std::enable_if_t<std::is_same_v<T, __int32>>* = nullptr>
    Int32(T value)
    {
        _Value = value;
    }
};

LIVE

【讨论】:

  • int 不需要 32 位,所以 int -> std::int32_t -> Int32int -> bool -> Boolean 仍然是模棱两可的。
  • @Jarod42 是的,我们需要更多的控制取决于 OP 的场景;不仅通过int,而且通过longshort,...
  • 模板方式真的很不错!我绝对应该阅读更多关于模板的内容。谢谢你的提示:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-02
相关资源
最近更新 更多