SFINAE problem.

  • Thread starter christopher diggins
  • Start date
C

christopher diggins

I am trying to make compile time decisions based on whether a struct defines
a member type. It seems to be a job for SFNIAE but I am struggling:

#include <iostream>
#include <cstdlib>

using namespace std;

struct fu { };
struct bar { typedef int type; };

template<typename T, typename U = void>
struct is_true {
static const bool value = false;
};

template<typename T>
struct is_true<T, typename T::type> {
static const bool value = true;
};

int main() {
bool b;
b = is_true<fu>::value;
cout << b << endl;
b = is_true<bar>::value;
cout << b << endl;
system("pause");
};

However, this outputs:
0
0

I am looking at the following:
http://boost-consulting.com/boost/libs/utility/enable_if.html

But it doesn't seem to do what it is that I specifically need.
Any help would be greatly appreciated. TIA!
 
H

Howard Hinnant

"christopher diggins said:
I am trying to make compile time decisions based on whether a struct defines
a member type. It seems to be a job for SFNIAE but I am struggling:

#include <iostream>
#include <cstdlib>

using namespace std;

struct fu { };
struct bar { typedef int type; };

template<typename T, typename U = void>
struct is_true {
static const bool value = false;
};

template<typename T>
struct is_true<T, typename T::type> {
static const bool value = true;
};

int main() {
bool b;
b = is_true<fu>::value;
cout << b << endl;
b = is_true<bar>::value;
cout << b << endl;
system("pause");
};

However, this outputs:
0
0

Your code prints:

0
1

for me (CodeWarrior Pro 10 (beta)).

-Howard
 
C

christopher diggins

However, this outputs:
Your code prints:

0
1

for me (CodeWarrior Pro 10 (beta)).


Thanks for checking that out. So I am not entirely a bumbling idiot ;-)
I am using GCC 3.4.2. So, in theory is what I am doing here correct?
 
H

Howard Hinnant

Your code prints:

0
1

for me (CodeWarrior Pro 10 (beta)).


Thanks for checking that out. So I am not entirely a bumbling idiot ;-)
I am using GCC 3.4.2. So, in theory is what I am doing here correct?[/QUOTE]

Well I was about to say yes, but now I'm not so sure. I converted your
example to a compile time test and ran it on Comeau (thanks Greg!):

struct fu { };
struct bar { typedef int type; };

template<typename T, typename U = void>
struct is_true {
static const bool value = false;
};

template<typename T>
struct is_true<T, typename T::type> {
static const bool value = true;
};

int main() {
char test1[!is_true<fu>::value];
char test2[is_true<bar>::value];
};

and it failed there.

Assuming I understand what you're trying to do, try this instead:

template <class T>
struct has_type
{
private:
struct two {char x; char y;};
template <class U> static two test(...);
template <class U> static char test(typename U::type* = 0);
public:
static const bool value = sizeof(test<T>(0)) == 1;
};

struct fu { };
struct bar { typedef int type; };

int main() {
char test1[!has_type<fu>::value];
char test2[has_type<bar>::value];
}

That passes for me everywhere I tried it (including gcc 4.0).

-Howard
 
C

christopher diggins

[snip]
That passes for me everywhere I tried it (including gcc 4.0).

That is wonderful Howard, it works great on GCC 3.4.2, thank you very much!
 

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


Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top