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 { ty开发者_如何学Cpedef 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 = MyClass
Resove<B2>::type = MyClass
Resove<D1>::type = D1
Resove<D2>::type = MyClass
Resove<D3>::type = MyClass
or 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 Error
right?
When you substitute T
by D3
the 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.
精彩评论