2

Possible Duplicate:
“What happened to my SFINAE” redux: conditional template class members?

Why can't I pass other parameters to my template class? I'm trying to enable a specific parameter only if the type passed is a literal type. If it isn't, accept other types but do not enable the Case-Sensitive parameter.

Why does the below not compile?

#include <iostream>
#include <type_traits>

template<typename T>
struct is_literal
{
   enum{value = false};
};

template<>
struct is_literal<char>
{
   enum{value = true};
};

template<>
struct is_literal<char*>
{
   enum{value = true};
};

template<>
struct is_literal<const char*>
{
   enum{value = true};
};

template<typename Char, typename Traits, typename Alloc>
struct is_literal<std::basic_string<Char, Traits, Alloc>>
{
   enum
   {
      value = true
   };
};

template<typename T>
class Test
{
    public:
        bool Contains(T DataType, typename std::enable_if<is_literal<T>::value, bool>::type  CaseSensitive = true);
};

template<typename T>
bool Test<T>::Contains(T DataType, typename std::enable_if<is_literal<T>::value, bool>::type CaseSensitive)
{
    return true;
}


int main()
{
    Test<int> F;    //This line gives errors.. It gives none if I pass char, char*, const char*, std::string.
    F.Contains(1);
}
Community
  • 1
  • 1
Brandon
  • 22,723
  • 11
  • 93
  • 186

1 Answers1

3

SFINAE can only occur when substitution is performed during overload resolution. That means that you must have a function template. In this case, you have a non-template function in a class template. That does not work. You can add a default template parameter to fix this.

template <typename U = T>
bool Contains(U DataType, typename std::enable_if<is_literal<U>::value, bool>::type  CaseSensitive = true);
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • Hmm I couldn't get that working. I did: template template bool Test::Contains(U DataType, typename std::enable_if::value, bool>::type CaseSensitive) { return true; } – Brandon Dec 20 '12 at 20:45
  • @CantChooseUsernames : [Works here](http://liveworkspace.org/code/1b6ow5$0). – ildjarn Dec 20 '12 at 20:51
  • Hmm but then I get: |61|error: no matching function for call to 'Test::Contains(int)' – Brandon Dec 20 '12 at 20:56
  • 1
    @CantChooseUsernames : You never made a specialization for `int`, so that's exactly what _should_ happen... – ildjarn Dec 20 '12 at 20:57