2

Is it possible to make a string as a template parameter and how? Like

A<"Okay"> is a type.

Any string (std::string or c-string) is fine.

user1899020
  • 13,167
  • 21
  • 79
  • 154
  • 1
    Yes, but it is not terribly helpful because it doesn't behave as you would expect (it uses pointer equality, not string equality). – R. Martinho Fernandes Jul 11 '13 at 15:40
  • Well... you could probably make a variadic template that takes in a bunch of characters as template inputs. At least it would give you real string equivalence. `std::string` will not work though because template arguments must be [integral](http://home.roadrunner.com/~hinnant/TypeHiearchy.pdf) types. – Suedocode Jul 11 '13 at 15:59
  • Possible duplicate of [Strings as template arguments?](http://stackoverflow.com/questions/1826464/strings-as-template-arguments). See also [Non-type template parameters](http://stackoverflow.com/questions/5687540/non-type-template-parameters) – gx_ Jul 11 '13 at 16:01
  • @Aggieboy Or pointers or references to objects with external linkage. (String literals don't work because they don't have external linkage.) – James Kanze Jul 11 '13 at 16:07
  • @JamesKanze Ahh details; a reference is just a pointer, a pointer is just an int, and an int is an integral. XD – Suedocode Jul 11 '13 at 16:47
  • @Aggieboy Ah, for the good old days, when men were men, women were women, and pointers were ints. (I presume that your comment was facetious. The language, or course, considers them all very distinct types, even if on most modern machines, there is very little difference under the hood.) – James Kanze Jul 11 '13 at 16:56

2 Answers2

2

Yes, but you need to put it in a variable with external linkage (or does C++11 remove the requirement for external linkage). Basically, given:

template <char const* str>
class A { /* ... */ };

this:

extern char const okay[] = "Okay";

A<okay> ...

works. Note thought that it is not the contents of the string which define uniqueness, but the object itself:

extern char const okay1[] = "Okay";
extern char const okay2[] = "Okay";

Given this, A<okay1> and A<okay2> have different types.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
1

Here's one way to make the string contents determine uniqueness

#include <windows.h> //for Sleep()
#include <iostream>
#include <string>

using namespace std;

template<char... str>
struct TemplateString{
    static const int n = sizeof...(str);
    string get() const {
        char cstr[n+1] = {str...}; //doesn't automatically null terminate, hence n+1 instead of just n
        cstr[n] = '\0'; //and our little null terminate
        return string(cstr); 
    }
};

int main(){
    TemplateString<'O','k','a','y'> okay;
    TemplateString<'N','o','t',' ','o','k','a','y'> notokay;
    cout << okay.get() << " vs " << notokay.get() << endl;
    cout << "Same class: " << (typeid(okay)==typeid(notokay)) << endl;
    Sleep(3000); //Windows & Visual Studio, sry
}
Suedocode
  • 2,504
  • 3
  • 23
  • 41