重载决议适用于函数,但不适用于隐式构造函数参数

Overload resolution works on functions, but not with implicit constructor parameters

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

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

虽然具有重载 __int32bool 的函数可以编译并工作,但具有 class 的函数作为重载会导致 对重载函数的调用不明确.

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

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

问题是,给定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