c语上的运算符重载 [英] Ambiguous operator overload on clang

查看:79
本文介绍了c语上的运算符重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试编译此测试程序时:

When I try to compile this test program:

struct comma_guard
{
    template<class T>
    const comma_guard& operator,(T&&) const
    {
        return *this;
    }
};

struct foo {};
template<class T> T operator,(T x, foo)
{
    return x;
}

int main()
{
    (comma_guard(), foo());
}

我在clang上遇到编译错误:

I get a compile error on clang:

comma_guard.cpp:20:19: error: use of overloaded operator ',' is ambiguous (with operand types 'comma_guard' and 'foo')
    (comma_guard(), foo());
     ~~~~~~~~~~~~~^ ~~~~~
comma_guard.cpp:6:24: note: candidate function [with T = foo]
    const comma_guard& operator,(T&&) const
                       ^
comma_guard.cpp:13:21: note: candidate function [with T = comma_guard]
template<class T> T operator,(T x, foo)
                    ^

这在gcc上可以正常编译.从我对ADL查找的理解来看, comma_guard 中的成员函数应该是首选,因此不应模棱两可.这样对吗?这是c中的错误吗?另外,是否有变通办法,以便始终首选 comma_guard 中的运算符?

This compiles fine on gcc. From my understanding of ADL lookup, the member function in comma_guard should be preferred and so therefore shouldn't be ambiguous. Is this correct? Is this a bug in clang? Also, is there a workaround so that the operator in comma_guard will always be preferred?

更新:因此,当clang进行模板化时,似乎clang不认为它是类成员.因此,如果我这样定义 comma_guard ,它将起作用:

Update: So it seems clang doesn't consider it a class member when its templated. So if I define the comma_guard like this, it will work:

struct comma_guard
{
    struct any
    {
        template<class T>
        any(T&&);
    };
    const comma_guard& operator,(any) const;
};

根据C ++,哪个是正确的?

Which is correct according to C++?

推荐答案

根据我对ADL查找的理解,应该首选comma_guard中的成员函数,因此不应模棱两可.这是正确的吗?

From my understanding of ADL lookup, the member function in comma_guard should be preferred and so therefore shouldn't be ambiguous. Is this correct?


答案::在重载解析期间并根据标准§13.3.1/2&7个候选函数和参数列表[over.match.funcs]:


Answer: During overload resolution and according to the standard § 13.3.1/2 & 7 Candidate functions and argument lists [over.match.funcs]:

2 这组候选函数可以包含要针对同一参数列表解析的成员函数和非成员函数.

2 The set of candidate functions can contain both member and non-member functions to be resolved against the same argument list.

7 在每种情况下,候选都是功能模板时,都会使用模板参数推导来生成候选功能模板特化(14.8.3,14.8.2).然后以通常的方式将这些候选项作为候选项处理[126].

7 In each case where a candidate is a function template, candidate function template specializations are generated using template argument deduction (14.8.3, 14.8.2). Those candidates are then handled as candidate functions in the usual way [126].

[脚注 126 ]参数推导过程完全确定了功能模板专业化的参数类型,即,功能模板专业化的参数不包含模板参数类型.因此,除非另有说明否则,在剩下的重载解决方案中,将等效地处理函数模板的专业化和非模板函数(8.3.5).

[footnote 126] The process of argument deduction fully determines the parameter types of the function template specializations, i.e., the parameters of function template specializations contain no template parameter types. Therefore, except where specified otherwise, function template specializations and non-template functions (8.3.5) are treated equivalently for the remainder of overload resolution.

因此,就重载分辨率选择而言,模板成员重载运算符没有比无模板重载运算符具有更高的优先级.

Consequently, the template member overloaded operator hasn't have greater priority in terms of overload resolution picking than the template free overloaded operator.

即使GCC选择了免费的模板,重载的运算符 实时演示.

Even if it had GCC picks the free template overloaded operator LIVE DEMO.

因此,以我的拙见,这是GCC,它显示了不符合标准的行为,而Clang正确地抱怨了过载解析的歧义.

So in my humble opinion, here is GCC that shows a non standard compliant behaviour and Clang rightfully complains about overload resolution ambiguity.

还有解决方法,这样始终会首选comma_guard中的运算符吗?

Also, is there a workaround so that the operator in comma_guard will always be preferred?


答案:是,尽管有点难看:(comma_guard().operator,(foo()));


Answer: Yes although kinda ugly: (comma_guard().operator,(foo())); LIVE DEMO

这篇关于c语上的运算符重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆