program:

#include <stdio.h> struct bar_t { int value; template<typename T> bar_t (const T& t) : value { t } {} // edit: You can uncomment these if your compiler supports // guaranteed copy elision (c++17). Either way, it // doesn't affect the output. // bar_t () = delete; // bar_t (bar_t&&) = delete; // bar_t (const bar_t&) = delete; // bar_t& operator = (bar_t&&) = delete; // bar_t& operator = (const bar_t&) = delete; }; struct foo_t { operator int () const { return 1; } operator bar_t () const { return 2; } }; int main () { foo_t foo {}; bar_t a { foo }; bar_t b = static_cast<bar_t>(foo); printf("%d,%d

", a.value, b.value); }

output for gcc 7/8:

2,2

output for clang 4/5 (also for gcc 6.3)

1,1

It seems that the following is happening when creating the instances of bar_t :

For gcc, it calls foo_t::operator bar_t then constructs bar_t with T = int .

For clang, it constructs bar_t with T = foo_t then calls foo_t::operator int

Which compiler is correct here? (or maybe they are both correct if this is some form of undefined behaviour)