10

I've noticed a difference in behavior between Clang and GCC with following code:

class convertible {
public:
    operator int() { return 1; }

    template <typename T>
    operator T() { return 1; }
};


int main () {
    convertible x;
    switch (x) {}  // Clang: OK   GCC: Compile error
    return 0;
}

GCC returns error: default type conversion can't deduce template argument for ‘template<class T> convertible::operator T()’

Clang compiles code without errors and calls operator int()

I'm using Clang 6 and GCC 8. Both with std=c++11

Which compiler is correct in this case?

random
  • 3,868
  • 3
  • 22
  • 39
  • 1
    Where's SFINAE? – geza Jul 13 '18 at 16:59
  • MSVC compiles it too. – DeiDei Jul 13 '18 at 17:00
  • @geza I'm not an expert, but I think that second case can be disabled because T is invalid. But I don't really know, that's why I'm asking. – random Jul 13 '18 at 17:04
  • @random I think what you've mentioned is more overload resolution. But very interesting question! – W.F. Jul 13 '18 at 17:06
  • Out of curiosity, is the type `switch` will try to convert `convertible` to guaranteed? Is it guaranteed to be `int` or just some integral type? Does it depend on the `case` labels? If so, what happens here when there is no `case` label? – François Andrieux Jul 13 '18 at 17:09
  • @FrançoisAndrieux Not guaranteed. Just some integral or enumeration type: http://eel.is/c++draft/stmt.switch#2 – Justin Jul 13 '18 at 17:10
  • I'd say clang is correct. `int` is an integral type, so there is no need to instantiate `operator T()` with any `T`. Yes W.F., good question :) – geza Jul 13 '18 at 17:12
  • 1
    I vaguely remember some words in the standard that template conversion operators won't be considered for switch based type conversion. This is only a vague memory, but if someone finds it it will pretty much prove that gcc screwed up. – Yakk - Adam Nevraumont Jul 13 '18 at 17:13
  • @Yakk-AdamNevraumont: that would be logical, as there is no definite type to instantiate with. An integral type can be anything. – geza Jul 13 '18 at 17:16
  • @geza Yes: the duplicate target is what I was talking about. Looks like gcc is enumerating the conversion operators to find an integral one; and it shouldn't be enumerating the template ones. But because it does, it dies as it cannot determine if `operator T` is an integral conversion operator or not. – Yakk - Adam Nevraumont Jul 13 '18 at 17:48

0 Answers0