problem with SFINAE applied to class methods

  • Thread starter Peter Collingbourne
  • Start date
P

Peter Collingbourne

Hello

I am trying to do some template metaprogramming involving enabling or
disabling a method in a parameterised class based on some condition. I
am trying to use the Boost enable_if mechanism to do this, using the
SFINAE principle. Here is a simple example showing what I am trying to do:

1 #include <iostream.h>
2 #include <boost/utility/enable_if.hpp>
3
4 using namespace boost;
5
6 template <bool CanFoo> class A {
7
8 public:
9 typename enable_if_c<CanFoo>::type foo() {
10 cout << "Foo" << endl;
11 }
12
13 };
14
15 int main(int argc, char** argv) {
16 A<false> cant_foo;
17 cant_foo.foo();
18 A<true> can_foo;
19 can_foo.foo();
20 }

In this example the foo method in the A class is supposed to only exist
when the boolean template parameter is true, thus I expect only one
compiler error to occur on line 17. However when compiling this code I
get the following additional message from the compiler (gcc 3.2.2):

traits.cc: In instantiation of `A<false>':
traits.cc:16: instantiated from here
traits.cc:9: no type named `type' in `struct boost::enable_if_c<false, void>'

Obviously there is not meant to be a type 'type' in this struct, which
is what SFINAE is all about! Is this a bug in the compiler or am I
misunderstanding the principle? If so can someone suggest an alternative
way to do what I want?

Thanks
 
J

John Harrison

Hello

I am trying to do some template metaprogramming involving enabling or
disabling a method in a parameterised class based on some condition. I
am trying to use the Boost enable_if mechanism to do this, using the
SFINAE principle. Here is a simple example showing what I am trying to
do:

1 #include <iostream.h>
2 #include <boost/utility/enable_if.hpp>
3
4 using namespace boost;
5
6 template <bool CanFoo> class A {
7
8 public:
9 typename enable_if_c<CanFoo>::type foo() {
10 cout << "Foo" << endl;
11 }
12
13 };
14
15 int main(int argc, char** argv) {
16 A<false> cant_foo;
17 cant_foo.foo();
18 A<true> can_foo;
19 can_foo.foo();
20 }

In this example the foo method in the A class is supposed to only exist
when the boolean template parameter is true, thus I expect only one
compiler error to occur on line 17. However when compiling this code I
get the following additional message from the compiler (gcc 3.2.2):

traits.cc: In instantiation of `A<false>':
traits.cc:16: instantiated from here
traits.cc:9: no type named `type' in `struct boost::enable_if_c<false,
void>'

Obviously there is not meant to be a type 'type' in this struct, which
is what SFINAE is all about! Is this a bug in the compiler or am I
misunderstanding the principle? If so can someone suggest an alternative
way to do what I want?

Thanks

I think you are misunderstanding the principle. SNIFAE only applies
(AFAIK) to choice between alternative function templates (including member
function templates). When choosing the function template the fact that one
choice leads to a type error is not a problem, it just means that choice
is not made.

The following would seem to do what you want without using SNIFAE (or
enable_if)

#include <iostream>
#include <boost/static_assert.hpp>

using namespace boost;

template <bool CanFoo>
class A {

public:
void foo() {
BOOST_STATIC_ASSERT(CanFoo);
std::cout << "Foo" << std::endl;
}

};

int main(int argc, char** argv) {
A<false> cant_foo;
//cant_foo.foo();
A<true> can_foo;
can_foo.foo();
}


Remove the comment from cant_foo.foo() and you get a compile error.

john
 
H

Howard

Man, I hate acronyms! What's "SFINAE"?

(In the news business, most acronyms are spelled out the first time they're
used in an article. IMO [in my opinion], that would be a good idea in the
newsgroups as well. :))

-Howard
 
J

Jeff Flinn

Howard said:
Man, I hate acronyms! What's "SFINAE"?

Substitution Failure Is Not An Error.
(In the news business, most acronyms are spelled out the first time they're
used in an article. IMO [in my opinion], that would be a good idea in the
newsgroups as well. :))

In this case, (IMO) if you don't know what the acronym stands for you
probably aren't going to be able to contribute. :)

Jeff F
 
D

David Harmon

On Thu, 1 Jul 2004 14:01:25 -0400 in comp.lang.c++, "Jeff Flinn"
Substitution Failure Is Not An Error.
In this case, (IMO) if you don't know what the acronym stands for you
probably aren't going to be able to contribute. :)

But if the poster would spell it out, somebody else reading might learn
something.
 
J

Jeff Flinn

David Harmon said:
On Thu, 1 Jul 2004 14:01:25 -0400 in comp.lang.c++, "Jeff Flinn"



But if the poster would spell it out, somebody else reading might learn
something.

I googled SFINAE the first time I saw the acronym. I think that's why the
definition stuck with me. If I'd been spoon fed, who knows...

Jeff F
 
D

David Harmon

On Fri, 2 Jul 2004 08:01:48 -0400 in comp.lang.c++, "Jeff Flinn"
I googled SFINAE the first time I saw the acronym. I think that's why the
definition stuck with me. If I'd been spoon fed, who knows...

"Substitution Failure Is Not An Error" is sufficiently mysterious to
begin with.
 
P

Pete Becker

David said:
On Fri, 2 Jul 2004 08:01:48 -0400 in comp.lang.c++, "Jeff Flinn"


"Substitution Failure Is Not An Error" is sufficiently mysterious to
begin with.

Think of it as "now you see it, now you don't." Or, perhaps, NYSINYD.
 

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

Similar Threads

SFINAE 4
SFINAE not applying as expected. 1
what happened to my sfinae? 3
SFINAE and explicit instantiation 3
SFINAE 4
Using SFINAE with constructors 2
iterator_traits and SFINAE 7
SFINAE problem. 4

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top