I am using a SFINAE mechanism to deduce a type. Resolve<T>::type is deduced to T if class T doesn’t contain yes and it’s deduced to MyClass if it contains yes.
class MyClass {};
template<typename>
struct void_ { typedef void check; };
template<typename T, typename = void>
struct Resolve { typedef T type; };
template<typename T>
struct Resolve <T, typename void_<typename T::yes>::check> {
typedef MyClass type;
};
Now, I have the simple test classes as,
struct B1 { typedef int yes; }; // 1
struct B2 { typedef int yes; }; // 2
struct D1 {}; // 3
struct D2 : B1 {}; // 4
struct D3 : B1, B2 {}; // 5 <----
According to the logic following should be the result for above tests:
Resove<B1>::type = MyClassResove<B2>::type = MyClassResove<D1>::type = D1Resove<D2>::type = MyClassResove<D3>::type = MyClassor compiler error (due to ambiguity between B1, B2)
Strangely, in test case (5) it doesn’t happen so. The result is,
Resolve<D3>::type = D3;
Can anyone explain, what magic is happening specially for multiple inheritance ? Not getting compiler error is a standard compliant behavior ? Here is the demo.
Why would you expect a compiler error? You know SFINAE stands for
Substitution Failure Is Not An Errorright?When you substitute
TbyD3the expression becames ambiguous. Due to SFINAE, this failure is not considered an error and your specialization is simply removed as a candidate. It’s all about NOT getting a compiler error.