Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template name used without template parameter [duplicate]

Tags:

c++

I had been using "const ObjArray&" as the argument for the ObjArray template without thinking about it. It seems to work fine but it looked off when I read it again. Shouldn't it be "const ObjArray<T> &"? Is it OK to refer to template name without the parameter? Does it work below just because it is declared inline that compiler assumes T?

template <class T>
class ObjArray : public BArray
{
public:
    inline ObjArray() :
        BArray(sizeof(T), NULL)
    {
    }

    inline ObjArray(const ObjArray& src) :
        BArray(sizeof(T), NULL)
    {
        copyFrom((ObjArray&)src);
    }

    inline ObjArray(ObjArray& src) :
        BArray(sizeof(T), NULL)
    {
        copyFrom(src);
    }
    ...
};
like image 541
Yasser Asmi Avatar asked Apr 13 '14 16:04

Yasser Asmi


2 Answers

No, that usage is correct: Inside a class template, the class name refers to that instance of the template, so the template parameter is not neccesary:

template<typename T>
struct foo
{
    foo( const foo& ); //Copy ctor. foo is the same as foo<T>
};

This behaviour is well defined in the point 14.6.1 Locally declared names of the Standard (Emphasis mine):

14.6.1 Locally declared names [temp.local]
Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used with or without a template-argument-list. When it is used without a template-argument-list, it is equivalent to the injected-class-name followed by the template-parameters of the class template enclosed in <>. When it is used with a template-argument-list, it refers to the specified class template specialization, which could be the current specialization or another specialization.

Note that syntax is just an alias of the current template instance. If you need the same template with other parameter you need to specify it explicitly, with the classic syntax. For example:

template<typename U>
operator foo<U>() const //Implicit conversion to other instance of the template
{
    return ...;
}
like image 95
Manu343726 Avatar answered Oct 07 '22 04:10

Manu343726


Yes, it is correct c++ syntax. Regarding your question about it being inline, you could write it like this outside of the class declaration:

template<typename T>
foo<T>::foo(const foo&)
{}

And it would still be correct. Notice only the first foo carries the template parameter explicitly. Once it has been specified, the context is completely defined, and now you can use foo as a perfectly legal class name, so the foo parameter will refer to foo<T> automatically.

like image 28
technik Avatar answered Oct 07 '22 04:10

technik