User-defined implicit conversion of an enum class when calling an overloaded operator fails

∥☆過路亽.° 提交于 2020-01-02 04:03:14

问题


Consider the following example:

struct ConvertibleStruct {};

enum class ConvertibleEC {};

struct Target {
    // Implicit conversion constructors
    Target(ConvertibleStruct) {}
    Target(ConvertibleEC) {}
};

Target operator~(const Target& t) {
    return t;
}

Target anotherFunction(const Target& t) {
    return t;
}

int main() {
    ConvertibleStruct t;
    ConvertibleEC ec;

    ~t;                   // 1. Works finding the operator overloaded above
    ~ec;                  // 2. Fails to compile on clang 3.4 and gcc 4.8.2
    operator~(ec);        // 3. Works finding the operator overloaded above

    anotherFunction(ec);  // 4. Works
}

Compiler versions:

The above findings are for clang 3.4 and gcc 4.8.2. Test 2. actually compiles fine on gcc 4.7.3 with -std=c++11. Possibly a bug in early GCC C++11 implementation?

Assertions:

  • Given that 1. compiles, user-defined implicit-conversions are checked when calling the ~ operator.
  • Given that 4. compiles, user-defined implicit-conversions are checked for enum class objects.

Questions:

  • Are the above assertions correct?
  • If they are, why does 2. fail to compile?
  • Given that 2. fails to compile, why does 3. compile?

回答1:


The second test, ~ec runs into a peculiarity of the name lookup for operators in expressions: [over.match.oper]/3 (from the "ancient" N3797):

For a unary operator @ with an operand of a type whose cv-unqualified version is T1 [...]

The set of non-member candidates is the result of the unqualified lookup of operator@ in the context of the expression according to the usual rules for name lookup in unqualified function calls except that all member functions are ignored. However, if no operand has a class type, only those non-member functions in the lookup set that have a first parameter of type T1 or “reference to (possibly cv-qualified) T1”, when T1 is an enumeration type [...] are candidate functions.

So the ::operator~(const Target&) should not be found/used with a for an expression with a unary operator applied to an operand of type ConvertibleEC.


For the first, ~t, the operand is of class type and the above exception does not apply.

Both the third and the fourth test do not use operator lookup, but usual unqualified lookup. The usual unqualified lookup finds ::operator~(const Target&) (in cases 1 and 3) and anotherFunction (in case 4).



来源:https://stackoverflow.com/questions/27281500/user-defined-implicit-conversion-of-an-enum-class-when-calling-an-overloaded-ope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!