SFINAE, deduction vs. instantiation

China☆狼群 提交于 2019-12-01 17:08:36

In C++03 specification, the rule of SFINAE is a little vague, allowing compiler authors to go to any length to find substitution failure to result in SFINAE. The relevant text §14.8.2/2 from C++03 says,

- [...] If a substitution in a template parameter or in the function type of the function template results in an invalid type, type deduction fails [...]

It further explains few reasons for failure, but none of them actually says at what point the substitution failure should be considered as SFINAE. So I guess, your code may work fine in C++03 (or may not, depending on how the compiler authors interpret the text. It is confusing to me anyway).

But the wordings in C++11 has been improved removing the vagueness. It says in §14.8.2/8,

If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. [ Note: Access checking is done as part of the substitution process. —end note ] Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure.

The term "immediate context" is interesting, and I think it applies to your situation. More specifically, the substitution failure in the meta-function a_metafun is not considered "immediate context" of the function-type. It is ill-formed in C++11, not SFINAE.

But then, even though C++11 has introduced the phrase "immediate context" to make the text slightly better, still the definition of the phrase isn't clear enough. Here is one active issue:

SFINAE won't protect you there, the error happens after type deduction. However, this should work:

template < typename T, typename Type = typename T::type >
struct a_metafun { typedef Type type; };

By accesing T::type in a default template parameter we cause this to happen at substitution time, and at that time SFINAE kicks in.

Edit: After thinking some more, I'm not exactly sure why your current implementation fails. I think is because a_metafun has a member type type, one that causes a compilation error; it would be different if a_metafun didn't have a member type type at all.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!