0

I noticed something interesting when templates are used (and I'm still learning c++, so hopefully I haven't botched this sample code):

template <class T>
T Pyramid<T>::getValue(int row, int col) {
    return data[triangleNum[row] + col];
}

Why do we manually specify the T argument (as it is named in this function) as a class? Isn't it obvious T is going to be a class, or does this mean we can allow other data types to be used in the template?

So, if we were to re-create the array from scratch, could we do something like this, and if so, what data types are allowed, and what are the restrictions for this?

# template <class T, int length>
CustomArray<float, 365> dailyIncome;
IQAndreas
  • 8,060
  • 8
  • 39
  • 74
  • @user657267 It's related, as now I know `typename` is another possible value, but still does not answer the question about other data types, such as in my example, `int`. – IQAndreas Aug 24 '15 at 02:46
  • The answer is that `class` doesn't mean `class` in this context, it was simply repurposed for templates (before the `typename` keyword was introduced). – user657267 Aug 24 '15 at 02:47
  • IQAndreas: You might want to look at `std::array` for an example in the standard not too far off from your `CustomArray` – Chris Beck Aug 24 '15 at 03:11

1 Answers1

0

There are, broadly, two categories of template parameters.

  1. template<typename T> (This is more general than marking parameter T as a class or struct or union, as it can also include primitive types like int, bool, etc.)

  2. Integral constants, i.e. template<int i>. For instance the following construction is useful in some TMP techniques.

:

template<int k> struct Rank : Rank<k-1> {};
template<> struct Rank<0> {};

This template generates a hierarchy of Rank types which each inherit from one another, i.e. Rank<0> is a superclass of Rank<1> is a superclass of Rank<2> ...

Integral constants can be broadly construed to include char, and also pointers like int * or even a pointer to some struct. You can for instance template a class against a pointer to some fixed (static storage duration) instance of a struct of some type in memory somewhere, this can be useful.

You cannot template against anything with a ctor or dtor (when would they run?). You cannot template against a const char * string literal -- if you attempted to instantiate a type my_type<"foo"> you would never be able to refer to that type again, because when you typed my_type<"foo"> later you would get a different string literal "foo" and therefore a different pointer and a different type. (You can however template against a particular string with static storage duration.) You also cannot template against float either, because you might expect things like my_type<2.0/3> and my_type<6.0/9> to always give you the same type, and then get a rude surprise caused by floating point rounding.

You can also template against function pointers, that's sometimes really useful also.

Pointer-to-member-function templating is also possible, I've used that in the past when making some code that binds C++ classes to lua.

Here's the actual text of C++11 standard (14.1.4)

A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

(4.1) — integral or enumeration type,

(4.2) — pointer to object or pointer to function,

(4.3) — lvalue reference to object or lvalue reference to function,

(4.4) — pointer to member,

(4.5) — std::nullptr_t.

[ Note: Other types are disallowed either explicitly below or implicitly by the rules governing the form of template-arguments (14.3). — end note ] The top-level cv-qualifiers on the template-parameter are ignored when determining its type.

Actually I didn't know about lvalue reference, I've never actually used that, nor have I used pointer to member besides pointer to member function. I have templated against nullptr, that is also useful at times.

Chris Beck
  • 15,614
  • 4
  • 51
  • 87
  • You can have a `const char*` template parameter. You just can't use a string literal as an argument for such a parameter. [temp.arg.nontype]/2 – Brian Bi Aug 24 '15 at 02:57
  • thanks, I actually did not realize that. editing – Chris Beck Aug 24 '15 at 02:58
  • 1
    This doesn't mention template template parameters. – Yakk - Adam Nevraumont Aug 24 '15 at 03:07
  • Yakk: I read the question as asking specifically about "nontype template parameters", that's how I read the word "data type" in the question. If you want to add another answer with info about template template paramaters be my guest – Chris Beck Aug 24 '15 at 03:10