SFINAE

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • none

    #1

    SFINAE

    I am trying to understand SFINAE based on this wiki page:





    // Defines return type to be void for all types
    // besides int.
    template<typena me T>
    struct can_use_f {
    typedef void type;
    };

    template<>
    struct can_use_f<int{

    typedef int type;
    };

    // function with return type ::type.
    template<typena me T>
    typename can_use_f<T>::t ype f(T const &);

    int main() {

    f(1);
    f(1.);

    }



    I have made a slight modification so if f(1) is called f should have
    return type int. But it gives the error:

    /tmp/cclJK0dJ.o: In function `main':
    bob.cpp:(.text+ 0x95): undefined reference to `can_use_f<int> ::type
    f<int>(int const&)'
    bob.cpp:(.text+ 0xa5): undefined reference to `can_use_f<doub le>::type
    f<double>(doubl e const&)'
    collect2: ld returned 1 exit status

    Is this the correct execution steps:

    1) f(T const &) is called.
    2) the return type is decided based on the template parameter.
    3) if T != int return type is void. If T = int return type should be int
    (this does not work).
  • Victor Bazarov

    #2
    Re: SFINAE

    none" <""johs\"@(none ) wrote:
    I am trying to understand SFINAE based on this wiki page:
    >

    >
    >
    >
    // Defines return type to be void for all types
    // besides int.
    template<typena me T>
    struct can_use_f {
    typedef void type;
    };
    >
    template<>
    struct can_use_f<int{
    >
    typedef int type;
    };
    >
    // function with return type ::type.
    template<typena me T>
    typename can_use_f<T>::t ype f(T const &);
    >
    int main() {
    >
    f(1);
    f(1.);
    >
    }
    >
    >
    >
    I have made a slight modification so if f(1) is called f should have
    return type int. But it gives the error:
    >
    /tmp/cclJK0dJ.o: In function `main':
    bob.cpp:(.text+ 0x95): undefined reference to `can_use_f<int> ::type
    f<int>(int const&)'
    bob.cpp:(.text+ 0xa5): undefined reference to `can_use_f<doub le>::type
    f<double>(doubl e const&)'
    collect2: ld returned 1 exit status
    Of course it does. You declared the 'f' template function, but
    you haven't given it a body!
    Is this the correct execution steps:
    >
    1) f(T const &) is called.
    2) the return type is decided based on the template parameter.
    3) if T != int return type is void. If T = int return type should be
    int (this does not work).
    WHAT does not work? The Wikipedia article is not about that, is it?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • Davis King

      #3
      Re: SFINAE

      On Mar 27, 8:14 pm, none <""johs\"@(none )"wrote:
      I am trying to understand SFINAE based on this wiki page:
      >

      >
      // Defines return type to be void for all types
      // besides int.
      template<typena me T>
      struct can_use_f {
      typedef void type;
      >
      };
      >
      template<>
      struct can_use_f<int{
      >
      typedef int type;
      >
      };
      >
      // function with return type ::type.
      template<typena me T>
      typename can_use_f<T>::t ype f(T const &);
      >
      int main() {
      >
      f(1);
      f(1.);
      >
      }
      >
      I have made a slight modification so if f(1) is called f should have
      return type int. But it gives the error:
      >
      /tmp/cclJK0dJ.o: In function `main':
      bob.cpp:(.text+ 0x95): undefined reference to `can_use_f<int> ::type
      f<int>(int const&)'
      bob.cpp:(.text+ 0xa5): undefined reference to `can_use_f<doub le>::type
      f<double>(doubl e const&)'
      collect2: ld returned 1 exit status
      >
      Is this the correct execution steps:
      >
      1) f(T const &) is called.
      2) the return type is decided based on the template parameter.
      3) if T != int return type is void. If T = int return type should be int
      (this does not work).
      You get that linker error because you haven't defined the body of your
      f() function. You need to change it to be at least this:
      template<typena me T>
      typename can_use_f<T>::t ype f(T const &) {} // note the addition of
      {}


      However, this isn't SFINAE. It would be (sort of) if you hadn't added
      that typedef int type; declaration. But I think this example from
      wikipedia is pretty confusing. I would recommend you read
      http://www.boost.org/libs/utility/enable_if.html for a much clearer
      explanation of what SFINAN is all about and why you might want to use
      it.

      -Davis

      Comment

      • vandevoorde@gmail.com

        #4
        Re: SFINAE

        On Mar 28, 6:24 am, James Kanze <james.ka...@gm ail.comwrote:
        On Mar 28, 1:14 am, none <""johs\"@(none )"wrote:
        [...][...]
        I'm not sure that the Wikipedia example is
        well chosen, however.
        [...]

        FWIW, I've edited the Wikipedia article. It could still use at least
        two examples (one actually demonstrating a use of SFINAE to discover a
        type property, and another one showing enable_if).


        (And thanks for the plug!)

        Daveed

        Comment

        Working...