Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > SFINAE

Reply
Thread Tools

SFINAE

 
 
none
Guest
Posts: n/a
 
      03-28-2008
I am trying to understand SFINAE based on this wiki page:

http://en.wikipedia.org/wiki/SFINAE



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

template<>
struct can_use_f<int> {

typedef int type;
};

// function with return type ::type.
template<typename T>
typename can_use_f<T>::type 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<double>::type
f<double>(double 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).
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      03-28-2008
none" <""johs\"@(none) wrote:
> I am trying to understand SFINAE based on this wiki page:
>
> http://en.wikipedia.org/wiki/SFINAE
>
>
>
> // Defines return type to be void for all types
> // besides int.
> template<typename T>
> struct can_use_f {
> typedef void type;
> };
>
> template<>
> struct can_use_f<int> {
>
> typedef int type;
> };
>
> // function with return type ::type.
> template<typename T>
> typename can_use_f<T>::type 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<double>::type
> f<double>(double 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


 
Reply With Quote
 
 
 
 
Davis King
Guest
Posts: n/a
 
      03-28-2008
On Mar 27, 8:14 pm, none <""johs\"@(none)"> wrote:
> I am trying to understand SFINAE based on this wiki page:
>
> http://en.wikipedia.org/wiki/SFINAE
>
> // Defines return type to be void for all types
> // besides int.
> template<typename T>
> struct can_use_f {
> typedef void type;
>
> };
>
> template<>
> struct can_use_f<int> {
>
> typedef int type;
>
> };
>
> // function with return type ::type.
> template<typename T>
> typename can_use_f<T>::type 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<double>::type
> f<double>(double 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<typename T>
typename can_use_f<T>::type 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

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-28-2008
On Mar 28, 1:14 am, none <""johs\"@(none)"> wrote:
> I am trying to understand SFINAE based on this wiki page:


You'd probably be better off using an orignal source. Say the
Jusuttis and Vandevoorde. The Wikipedia is NOT the place to
learn how to use technical concepts.

> http://en.wikipedia.org/wiki/SFINAE


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


> template<>
> struct can_use_f<int> {
> typedef int type;
> };


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


> int main() {
> f(1);
> f(1.);
> }


There's no SFINAE in your example. SFINAE occurs during
template argument type deduction, and is used to eliminate
certain functions from the overload set (so they won't be
considered and chosen later). Since there's no failure to
deduce template arguments in your code, there's no SFINAE.

Note that your code doesn't correspond to that in the Wikipedia
article, since you've ensured that template argument deduction
will always work. (I'm not sure that the Wikipedia example is
well chosen, however. The usual use of SFINAE is exactly what
the article says in its first sentence: "used when resolving
overloaded functions or templates". Providing an example which
doesn't involve overloading, but uses SFINAE to provoke a later
error, seems rather contradictory. At the very least, some
explination as to how this is used for concept checking would
have been in order.)

> 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<double>::type
> f<double>(double const&)'
> collect2: ld returned 1 exit status


That's because you haven't provided an implementation for the
function.

> 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).


Of course it does. Just provide an implementation of the
function, and there's no problem. (Note that your error
messages come from the linker.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
vandevoorde@gmail.com
Guest
Posts: n/a
 
      03-31-2008
On Mar 28, 6:24*am, James Kanze <(E-Mail Removed)> wrote:
> On Mar 28, 1:14 am, none <""johs\"@(none)"> wrote:

[...]
> >http://en.wikipedia.org/wiki/SFINAE

[...]
> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
SFINAE kaalus@gmail.com C++ 4 04-26-2006 02:08 PM
SFINAE problem. christopher diggins C++ 4 09-26-2005 06:25 PM
Using SFINAE with constructors Clark S. Cox III C++ 2 09-09-2005 09:34 PM
SFINAE compilation troubles justin.adam.miller@gmail.com C++ 3 02-08-2005 08:47 AM
problem with SFINAE applied to class methods Peter Collingbourne C++ 8 07-04-2004 07:25 PM



Advertisments