SFINAE

N

none

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

Victor Bazarov

none" <""johs\"@(none) said:
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
 
D

Davis King

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
 
J

James Kanze

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

vandevoorde

[...]
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top