Quantcast
Viewing all articles
Browse latest Browse all 22162

GCC C++ bug? (T)x matching X::operator const T&() const differs from clang's

I've encountered a discrepancy between GCC and clang (big range of versions thereof tested at godbolt - all had same discrepancy) with conversion operator matching. Now using Barry's shorter reproduction code - also available at godbolt.

struct X {
    template <typename T>
    operator T const&() const;
};

int i = X();

Should operator T const&() const match when converting to int (clang says yes / GCC needs operator T() const to avoid:

<source>:6:9: error: cannot convert 'X' to 'int' in initialization
        6 | int i = X();
          |         ^~~

The relevant part of the C++17 Standard is 15.3 Conversions [class.conv]. Therein, 15.3.5 says...

Function overload resolution (16.3.3) selects the best conversion function to perform the conversion.

...which is almost what's important. 16.3.3 is the section for Best viable function [over.match.best], but usually works in combination 16.3.2 viable functions [over.match.viable]. The Standard doesn't seem explicit about whether 16.3.2 applies here, but assuming it does, we have in 16.3.2.1:

From the set of candidate functions constructed for a given context (16.3.1), a set of viable functions is chosen

Which raises the question of whether GCC considers operator const T&() const a candidate that's not viable, or not even a candidate. The requirements for a candidate to be valid are very simple though: right number of arguments, and that "there shall exist for each argument an implicit conversion sequence (16.3.3.1) that converts that argument to the corresponding parameter...", which is obviously true here, so I believe GCC must not consider operator const T&() const a candidate, which takes us to 16.3.1 Candidate functions and argument lists [over.match.funcs], and specifically 16.3.1/7:

In each case where a candidate is a function template, candidate function template specializations are generated using template argument deduction (17.8.3, 17.8.2). Those candidates are then handled as candidate functions in the usual way.

Given say template <typename T> void f(const T&); could be called with an int argument type, I'd think GCC should have considered the conversion operator a valid candidate, just like clang does.

I'd appreciate confirmation / thoughts though. If folks are in agreement, I'll raise a bug report against GCC.


Viewing all articles
Browse latest Browse all 22162

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>