Abhishek Singh
Abhishek Singh

Reputation: 31

A template can pass argument types without loss of information

Straustrup speaks about the template arguments being passed without loss of information in his book, The C++ programming language, "A template can pass argument types without loss of information;"

What does he mean by loss of information here ?

template <typename T>
T sum (T a, T b)
{
    return a + b;

}

int main ()
{
  long l = 212;
  sum<short> (l, l);
}

Visual C++ 11 compiler returns a warning

warning C4244: 'argument' : conversion from 'long' to 'short', possible loss of data

Is this what he is referring to ?

Upvotes: 1

Views: 120

Answers (4)

marcinj
marcinj

Reputation: 49986

He is not refering to values but to the type of argument. In your example type T will be short int, it will not be changed. This allows compilers to perform various optimizations - like inlining, and also makes type safety better.

you can verify that type is preserved using below trick with TD template:

template<typename T> class TD;

template <typename T>
T sum (T a, T b)
{
    TD<T> aaa;
    return a + b;

}

int main ()
{
  long l = 212;
  sum<short> (l, l);
}

compiler will issue an error giving you information of what type T actually is, for gcc that would be:

main.cpp: In instantiation of 'T sum(T, T) [with T = short int]':
main.cpp:14:19:   required from here
main.cpp:6:11: error: 'TD<short int> aaa' has incomplete type
     TD<T> aaa;

T = short int

so type is preserved

Upvotes: 0

Richard Hodges
Richard Hodges

Reputation: 69874

His point might be better illustrated by making a small modification to the program:

#include <iostream>
#include <typeinfo>

template <typename T>
T sum (T a, T b)
{
    std::cout << "summing two values of type: " << typeid(T).name() << std::endl;
    return a + b;

}

int main ()
{
    long l = 212;
    sum(l, l);

    short s = 212;
    sum(s, s);
}

example output: (may be different if you're on Visual Studio)

summing two values of type: l
summing two values of type: s

Note that the full type information is available within each instantiation of the template function. This allows the compiler to perform full type-checking at compile time, decreasing the chance of a programming error that needs to be caught at run time.

Upvotes: 0

luk32
luk32

Reputation: 16070

Nope.

If you wanted to make a generic sum function with out using template you would need to choose a particular type for implementation. This forces type-conversion, ergo possible loss of information.

The template let's you write sum(l,l) for any type and you don't lose anything. You can write sum(string1, string2), no problem. In other words. Inside the sum definition you know the original type of the operand.

By choosing the type explicitly you purposely disable this mechanism, by forcing compiler into using an instantiation of your choice. This is no different than writing sum with explicit type. In your case you accidentally force type narrowing. But the actual types used do not matter.

His words were not about integer conversion. At least I would presume so. Templates are more important and have bigger purpose than avoiding type narrowing.

Upvotes: 1

Bathsheba
Bathsheba

Reputation: 234685

In writing sum<short> (l, l); you are insisting that the compiler calls the short version of sum: i.e. short sum (short a, short b)

In doing that, the ls are converted to short types. That is what your compiler is warning you about: you're only a hair's breadth away from undefined behaviour if l is too big for a short. This process is nothing to do with the template function itself, so Stroustrup's assertion still holds: there is no loss of type information at compile time.

Upvotes: 3

Related Questions