c++language-lawyertype-deductionc++23explicit-object-parameter

Combined with C++23 Deducing this and conversion operator with auto return type?


I recently noticed a strange issue regarding C++23 Deducing this feature.

Suppose we have a struct S with a simple conversion operator:

struct S {
  operator int() { return 42; }
};

int i = S{};

Since 42 is of type int, we can specify the return type of the conversion operator as auto, for example:

struct S {
  operator auto() { return 42; }
};

int i = S{};

This is totally fine. If we apply C++23 Deducing this feature on it, it would be:

struct S {
  operator auto(this S) { return 42; }
};

int i = S{};

This is totally fine too. However, when I replace this S with this auto:

struct S {
  operator auto(this auto) { return 42; }
};

int i = S{};

All three compilers reject the above code. GCC gives:

<source>:5:9: error: cannot convert 'S' to 'int' in initialization
    5 | int i = S{};

However, when I change the return type of the conversion operator back to int, then all three compilers compile fine:

struct S {
  operator int(this auto) { return 42; }
};

int i = S{};

This confuses me.

Why does the compiler reject operator auto(this auto) { return 42; }? I see no reason to reject it as it seems intuitive to me. So I'm wondering what does the standard say about this? Or is this a compiler bug?


Solution

  • This is CWG1878.

    [class.conv.fct]p9:

    A conversion function template shall not have a deduced return type.

    operator auto(this auto) is an abbreviated function template, so it is not valid.

    The reason it was disallowed is that it was of limited use at the time and I think GCC had a very difficult time with naming this function (See also: CWG1670)

    You see the same behaviour for something like this:

    template<int = 0>
    operator auto() { return 42; }