c++ - 为什么隐式转换对于非原始类型不模棱两可?

标签 c++ templates c++17 implicit-conversion ambiguous

给定一个具有多个隐式转换函数(非显式构造函数和转换运算符)的简单类模板,如下例所示:

template<class T>
class Foo
{
private:
    T m_value;

public:
    Foo();

    Foo(const T& value):
        m_value(value)
    {
    }

    operator T() const {
        return m_value;
    }

    bool operator==(const Foo<T>& other) const {
        return m_value == other.m_value;
    }
};

struct Bar
{
    bool m;

    bool operator==(const Bar& other) const {
        return false;
    }
};

int main(int argc, char *argv[])
{
    Foo<bool> a (true);
    bool b = false;
    if(a == b) {
        // This is ambiguous
    }

    Foo<int> c (1);
    int d = 2;
    if(c == d) {
        // This is ambiguous
    }

    Foo<Bar> e (Bar{true});
    Bar f = {false};
    if(e == f) {
        // This is not ambiguous. Why?
    }
}

涉及原始类型(boolint)的比较运算符是模棱两可的,正如预期的那样 - 编译器不知道是否应该使用转换运算符来转换左- 将模板类实例转换为原始类型或使用转换构造函数将右侧原始类型转换为预期的类模板实例。

然而,最后一个比较,涉及一个简单的 struct,并没有歧义。为什么?将使用哪个转换函数?

使用编译器 msvc 15.9.7 测试。

最佳答案

根据[over.binary]/1

Thus, for any binary operator @, x@y can be interpreted as either x.operator@(y) or operator@(x,y).

根据这条规则,在 e == f 的情况下, 编译器只能解释为 e.operator==(f) ,而不是 f.operator==(e) .所以没有歧义; operator==您定义为 Bar 的成员根本不是重载解决方案的候选者。

a == b 的情况下和 c == d , 内置候选 operator==(int, int) (参见 [over.built]/13)与 operator== 竞争定义为 Foo<T> 的成员.

关于c++ - 为什么隐式转换对于非原始类型不模棱两可?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55249017/

相关文章:

c++ - 成员(member)使用无效

c++ - 强制非专用模板实例化出现编译错误

c++ - 有没有办法将模板的替换失败转换为 bool 值(真/假)或标签(std::true_type/std::false_type)

c++ - C++中#undef的含义

c++ - 将 time_point 降低到给定持续时间的推荐方法

c++ - 在 std::function 中使用模板参数

C# Sitecore 获取继承模板

c++ - 如何构造一个类型特征来判断一个类型的私有(private)方法是否可以在另一种类型的构造函数中调用?

c++ - 解决 CRTP 函数重载歧义

c++ - 编译 C++ 程序时出错