1

I am writing a TMP to count the number of elements passed to a struct as template parameters using variadic templates. This is my code:

template<class T, T... t>
struct count;

template<class T, T h, T... t> 
struct count<T, h, t...>{
 static const int value = 1 + count<T, t...>::value;
};

template<class T>
struct count<T>{
 static const int value = 0;
};

template<>
struct count<std::string, std::string h, std::string... l>{
 static const int value = 1 + count<std::string, l...>::value;
};

template<>
struct count<std::string>{
 static const int value = 0;
};

int main(){
 std::cout << count<int, 10,22,33,44,56>::value << '\n';
 std::cout << count<bool, true, false>::value << '\n';
 std::cout << count<std::string, "some">::value << '\n';
 return 0;

}

I get an error on the third instantiation of count with std::string because g++ 4.7 tells me error: ‘class std::basic_string<char>’ is not a valid type for a template non-type parameter. Any workaround for this?

badmaash
  • 4,775
  • 7
  • 46
  • 61
  • 1
    What about the variadic `sizeof...`? Also, class-types cannot appear as non-type template arguments, nor can string literals. – Kerrek SB Jul 20 '12 at 22:50
  • `sizeof...` just made the specializations disappear. Thank you. But is there a different way for what i am trying to achieve? – badmaash Jul 20 '12 at 23:07
  • What *are* you trying to achieve? (I don't mean "what do you think is the solution", but really what your ultimate problem is.) – Kerrek SB Jul 20 '12 at 23:08
  • I am reading Milewski's blog: http://bartoszmilewski.com/2009/10/21/what-does-haskell-have-to-do-with-c/ and trying to emulate what he did in it but not for types. – badmaash Jul 20 '12 at 23:17

2 Answers2

2

The problem is not the type std::string but the literal "some" in your call

std::cout << count<std::string, "some">::value << '\n';

Unfortunately, it is not possible to pass a string or floating point literal to a template as is also written in this answer or in that one.

Community
  • 1
  • 1
Mehrwolf
  • 8,208
  • 2
  • 26
  • 38
1

Sorry to disappoint you, but there's no way around this. Non-type template parameters can only be primitive types such as:

  • integral or enumeration
  • pointer to object or pointer to function
  • reference to object or reference to function
  • pointer to member

std::string or other types simply don't work there.

marton78
  • 3,899
  • 2
  • 27
  • 38