SFINAE, deduction vs. instantiation

前端 未结 2 2022
[愿得一人]
[愿得一人] 2021-01-18 10:36

This code fails to compile in most compilers but at first I intuitively expected SFINAE to protect me:

typedef void (*A)();

template < typename T >
st         


        
相关标签:
2条回答
  • 2021-01-18 11:14

    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.

    0 讨论(0)
  • 2021-01-18 11:26

    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:

    • 1844. Defining “immediate context”
    0 讨论(0)
提交回复
热议问题