Thursday, August 31, 2006

Unusable Feature


Templates are a powerfull feature of the C++ programing language. But they where introduced later into the language which leaded to some problems in conjunction with other parts of the language. Here is one of them:

A compiler can ascertain type and non-type template arguments from a call if the function arguments identify the template arguments unequivocaly. (See Bjarne Stroustrup, the C++ programing language, 4th edition, chapter 13.3.1). If the template arguments can not be ascertained they have to be provided. For example

template <class T>
void foo(T t)
{
    cout << typeid(T).name() << endl;
}

template <class T>
void bar()
{
    cout << typeid(T).name() << endl;
}

int main()
{
    foo(3);
    bar<int>();
}   

prints twice "i", which is the typename of integers.
Combining template functions with classes leads to member templates where the same things count. Even constructors can be templates.

class Foo {
public:
    template<class T> 
    Foo(T t)
    {
        cout << typeid(T).name() << endl;
    }
};

int main()
{
    Foo f(3);    
}

This example again prints "i". So what's the problem then? Here it is:

class Bar {
public:
    template<class T> 
    Bar()
    {
        cout << typeid(T).name() << endl;
    }
};

If you find a way how to instantiate an object of type Bar you are my C++ guru. AFAICS there is no way. This is because constructors are only almost like functions. Using the typename as an implicit function call means one can not provide template arguments to the function because the syntax allows only template parameters for the type.
Here goes some tries and the output of the g++ 3.3.5:

Bar<int> b();  // non-template type `Bar' used as a template
Bar b<int>();  // template-id `b<int>' in declaration of primary template

AFAICS this case was just forgotten when the standard was written. At least I could not find any hints on this anywhere. If you know more about this topic please mail me.

No comments:

Post a Comment