SFINAE



  • #include <iostream>
    
    template <int V>
    void div(char(*)[V % 2 == 0] = 0)
    {
    	std::cout << "V is even" << std::endl;
    }
    template <int V>
    void div(char(*)[V % 2 == 1] = 0)
    {
    	std::cout << "V is odd" << std::endl;
    }
    
    int main()
    {
    	div<4>();
    	div<5>();
    }
    

    Kann mir jemand erklären, was für Elemente der TMP hier zum Einsatz kommen? Und wieso das trotz der Regel $8.3.4.1: "[...]If the constant-expression is present, it shall be an integral constant expression and its value shall be greater than zero.[...]"
    Kompiliert?



  • Mr.L schrieb:

    Und wieso das trotz der Regel $8.3.4.1: "[...]If the constant-expression is present, it shall be an integral constant expression and its value shall be greater than zero.[...]"
    Kompiliert?

    Nunja, genau das ist es doch, was SFINAE aussagt. https://de.wikipedia.org/wiki/Substitution_failure_is_not_an_error


  • Mod

    §14.8.3/1 schrieb:

    If, for a given function template, argument deduction fails, no such function is added to the set of candidate functions for that template.

    §14.8.2/8 schrieb:

    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, with a diagnostic required, if written using the substituted arguments.
    [ Note: If no diagnostic is required, the program is still ill-formed. 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.

    Auch durch eine Note erwähnt:

    [ Note: Type deduction may fail for the following reasons:
    (8.2) — […] or attempting to create an array with a size that is zero or negative.

    Und die Regel bezüglich Arrays benötigt in der Tat eine Diagnostik:

    §8.3.4/1 schrieb:

    If the constant-expression (5.20) is present, it shall be a converted constant expression of type std::size_t and its value shall be greater than zero.

    Die Tatsache, dass es ein Zeiger auf ein Array ist, ist unerheblich; Der Array-Typ wird ja trotzdem indirekt erzeugt. Lesenswert ist definitiv folgende Diskussion auf dem GCC Bug Tracker: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17232

    Edit²: Huch, irgendwie ist das nach oben gerutscht. Das werd' ich auf die Forensoftware schieben.



  • Arcoth schrieb:

    §14.8.3/1 schrieb:

    If, for a given function template, argument deduction fails, no such function is added to the set of candidate functions for that template.

    Ah, deshalb funktioniert auch das:
    https://ideone.com/xDmw5M
    und das hier nicht:
    https://ideone.com/0teM3L
    Genau was ich gesucht habe, danke!


Log in to reply