#include <type_traits>

struct T2;
struct T1 {
    T1(){}
    T1(int){}
    operator T2();
};
struct T2 {
    operator int() { return 0; }
};
struct T3 {
    operator int() { return 0; }
};
T1::operator T2() { return T2(); }

using namespace std;
using X = T1;
using Y = T2;
using Z = T3;
int main()
{

    true?T2():T3(); // int
    static_assert(std::is_same<std::common_type_t<T2,
                                                  T3>,
                               int>::value,
                  "Not int");

    true?T1():(true?T2():T3()); // T1
    static_assert(std::is_same<std::common_type_t<T1,
                                                  std::common_type_t<T2,
                                                                     T3>>,
                               T1>::value,
                  "Not T1");

    // -----------------------------------------

    true?T1():T2(); // T2
    static_assert(std::is_same<std::common_type_t<T1,
                                                  T2>,
                               T2>::value,
                  "Not T2");

    true?(true?T1():T2()):T3(); // int
    static_assert(std::is_same<std::common_type_t<std::common_type_t<T1,
                                                                     T2>,
                                                  T3>,
                               int>::value,
                  "Not int");

    // -----------------------------------------

    static_assert( is_same<common_type_t< X, common_type_t<Y,Z>    >,
                           common_type_t<    common_type_t<X,Y>, Z > >::value,
                    "Don't match");
}