post  Another easy one

twoscoops (15)   Link to this post
Ok, I'm trawling through the tutorials, and have got to templates, the syntax of which is a little baffling, although the concept reasonably straightforward. I had this test question below, can you tell me why the right answer is the right answer! TIA.

Which of the following is an invalid template declaration:

a) template <int x> int func() {return x;}
b) template <double x> double func() {return x;}
c) template <typename x> void func(x t) {}
Disch (2161)   Link to this post
I honestly don't know the answer to this one. =x If I had to guess I'd say B, only because double is a nonintegral type and maybe C++ templates don't like that. But I don't know for sure.

On a somewhat related note: I never understood the point of using variables as template parameters (like a or b in your example -- what's the point?). I mean why not just pass them as a function/ctor parameter. Does anyone know why they'd be benefitial?
guestgulkan (1307)   Link to this post
My guess.
b is wrong because only integer (integral) types are are allowed is template decalartions like that (see example a).
jsmith (3807)   Link to this post
B.

@Disch:

One example I use quite often:

1
2
3
template< typename T, size_t N >
size_t ArraySize( T (&)[ N ] )
{ return N; }


is a handy way of computing the size of a fixed length array without having to create a #define or const for it.

Another (simplistic) example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template< typename T, size_t N >
size_t asize( T (&)[ N ] )
{ return N; }

template< typename T, size_t N >
T* abegin( T (&a)[ N ] )
{ return a; }

template< typename T, size_t N >
T* aend( T (&a)[ N ] )
{ return a + N; }

//And now this works:
static int int_array[] = { 1, 2,3, 4, 5, 6, 7, 8, 9, 10 };
std::cout << std::accumulate( abegin( int_array ), aend( int_array ), 0 );


twoscoops (15)   Link to this post
well, yes, the answer is b) but sadly I'm non the wiser as to why?

or sizeof (array) / sizeof (array[0]); C, I know, but seems a lot simpler than the stuff above, well to me anyway !
Last edited on
guestgulkan (1307)   Link to this post
From C++ Templates - the complete guide book 4.3 Restrictions for Nontype Template Parameters
Note that nontype template parameters carry some restrictions.
In general, they may be constant integral values (including enumerations) or
pointers to objects with external linkage.

Floating-point numbers and class-type objects are not allowed as nontype template parameters:

template <double VAT> // ERROR: floating-point values are not
double process (double v) // allowed as template parameters
{
return v * VAT;
}

template <std::string name> // ERROR: class-type objects are not
class MyClass { // allowed as template parameters

};
Not being able to use floating-point literals (and simple constant floating-point expressions)
as template arguments has historical reasons. Because there are no serious technical
challenges, this may be supported in future versions of C++ (see Section 13.4 on page 210).



Last edited on
jsmith (3807)   Link to this post
@twoscoops:

It is arguably simpler to understand how the sizeof method works, but it is not simpler to use, and it is definitely much more prone to misuse. Example:

1
2
3
4
5
6
7
8
9
int main() {
    int* parray = new int[ 10 ];

    // Compiles, but gives wrong answer (runtime bug)
    std::cout << "Size of array is " << (sizeof(parray)/sizeof(parray[0]));

   // Does not compile (compile time bug)
   std::cout << "Size of array is " << ArraySize( parray );
}


I'd rather have compile time bugs than runtime bugs.
Last edited on
twoscoops (15)   Link to this post
Nah, gives exactly the right answer! sizeof of a pointer / sizeof of first element. Simples.
twoscoops (15)   Link to this post
From C++ Templates - the complete guide book
4.3 Restrictions for Nontype Template Parameters
Note that nontype template parameters carry some restrictions.
In general, they may be constant integral values (including enumerations) or
pointers to objects with external linkage.

Floating-point numbers and class-type objects are not allowed as nontype template parameters:

template <double VAT> // ERROR: floating-point values are not
double process (double v) // allowed as template parameters
{
return v * VAT;
}

template <std::string name> // ERROR: class-type objects are not
class MyClass { // allowed as template parameters

};
Not being able to use floating-point literals (and simple constant floating-point expressions)
as template arguments has historical reasons. Because there are no serious technical
challenges, this may be supported in future versions of C++ (see Section 13.4 on page 210).


template <double VAT>

I don't understand why this is a template? As it is specifying the type....... v confused.


Disch (2161)   Link to this post
template <double VAT>

I don't understand why this is a template? As it is specifying the type....... v confused.


The 'template' keyword is a dead givaway =P

</wiseass>

Template declarations are the same as non-template declarations, only they're prefixed by the template keyword (and any template arguments).

IE:

1
2
3
4
5
6
// a non-template function
void foo(int bar) { }

// a template function
template <typename T>
void foo(T bar) { }


Syntax for each is exactly the same, but the template keyword slips in before the rest (even before the return type). That is what makes it a template.

But again note that you can't use double as a template parameter.
twoscoops (15)   Link to this post
No, sorry, doesn't make any sense whatsoever.

template <int x> int func() {return x;} This is apparently a template, why?
template <double x> double func() {return x;} this is not even legal, why? apart from undefined historical reasons.

Now I can understand why this :-

template <typename T> is a template as we haven't defined the type

But the two at the top, why bother with the word template??

1) func returns and int and takes no parameters, what else can it do? what flexibility does the template <int x> do ?
2) Not even legal, but why oh why, just dump the template <double x> specifier.
jsmith (3807)   Link to this post
You are right, the first two (the second one if legal) are pointless. There is no need for the template.

This topic is archived - New replies not allowed.