views:

177

answers:

3

Possible Duplicate:
C++ template gotchas

Hi,

I am just in to my second month on SO, and I have seen enough number of posts on SO related to several common issues with templates. Is it a good idea to make a small Wiki on this (sadly I don't know how to make one)?

The idea is to provide a reference as definitive as this (GMan's favourite)

Here is the first one from me

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

If there already exists one or if this idea is not appealing, please feel free to vote it for closure. I will also vote for it :)

+1  A: 

A quick summary of typename

The typename keyword has two meanings in C++. typename can be used as a substitute for class in template parameter lists.

// These two lines mean exactly the same thing.
template<typename A> class Foo {};
template<class A> class Foo {};

The other reason is more complicated. typename tells a compiler that a dependent name is in fact a type.

Consider:

template<typename T>
struct Bar
{
    typedef T MyType; // Okay.
    typedef T::Type OtherType; // Wrong.
};

This is wrong because the compiler thinks that T::Type is not in fact a type, so the typedef fails. T might define Type as something that's not a type (like a static member), so the compiler must default to treating T::Type as a non-type since it doesn't know what T is until it is instantiated. In this situation, T::Type is what standardese calls a dependent name. Note that T is a non-dependent name because the compiler knows that T is in fact a type (it's one of the template type parameters), so that doesn't require typename.

In this case, you must give a hint to the compiler:

template<typename T>
struct Bar
{
    typedef T MyType; // Okay.
    typedef typename T::Type OtherType; // Okay.
};

Unfortunately, due to compiler bugs, a compiler may compile the snippet without typename without errors, even though it is not legal!

In silico
+1  A: 

some fun stuff with deduced template types.

compilers treat the following cases differently.

struct F {
    typedef int value_type;
};

struct B : F {
    B::value_type value;          // some compilers, edg
    typename B::value_type value;  // other compilers, gcc
    BOOST_DEDUCED_TYPENAME B::value_type value;  // Boost!!!
};

to make this crazy, nvcc cuda compiler is actually two compilers, edg and gcc, rolled into one which both process the same file. however, typename deduction is different for both of them, so it makes BOOST_DEDUCED_TYPENAME unsuitable. :-(

aaa
A: 

Dependent bases are never searched during unqualified name lookup

struct base{
    virtual void f(){}
};

template<class T> struct anotherbase{
    virtual void f(){}
};

template<class T> struct derived : base, anotherbase<T>{
    void g(){f();}
};

int main(){
    derived<int> d;
    d.g();             // not ambiguous. should call base::f
                        // unqualified name 'f' is not looked up 
                        // anotherbase<int>
}
Chubsdad