visual studio - C++ idioms when declaring template class members and constructors -
although both of following compile (with visual studio 2013), 1 of them more "correct" respect c++ idioms? speak particularly respect explicit template parameters when calling base class constructors , declaring members. standard have view on this? there practical reason prefer 1 on other?
template<class t> class bar1 : public base<t> { public: bar1() : base() {} bar1(t value) : base(value) {} bar1(bar1 const & other) : base(other.value) {} void foo(bar1 const & other) { // foo related activity. } }; template<class t> class bar2 : public base<t> { public: bar2() : base<t>() {} bar2(t value) : base<t>(value) {} bar2(bar2<t> const & other) : base<t>(other.value) {} void foo(bar2<t> const & other) { // foo related activity. } };
this question relies on called injected-class-name. [class]
a class-name inserted scope in declared after class-name seen. class-name inserted scope of class itself; known injected-class-name. purposes of access checking, injected-class-name treated if public member name.
and [temp.local]:
like normal (non-template) classes, class templates have injected-class-name (clause 9). injected-class-name can used template-name or type-name. when used template-argument-list, template-argument template template-parameter, or final identifier in elaborated-type-specifier of friend class template declaration, refers class template itself. otherwise, equivalent template-name followed template-parameters of class template enclosed in
<>.
that is, within definitions bar1<t> or bar2<t>, can use bar1 or bar2 refer full class type. is, these declarations equivalent:
void foo(bar2<t> const & other); void foo(bar2 const & other); however, rules lookup apply normal. while there is injected-class-name base, dependent name , cannot found via normal unqualified lookup. [temp.dep]:
in definition of class or class template, scope of dependent base class (14.6.2.1) not examined during unqualified name lookup either @ point of definition of class template or member or during instantiation of class template or member.
which makes this:
bar1() : base() {} ill-formed. base unqualified lookup, , there no such name base. there base<t>::base (the injected-class-name there), scope unexamined. have either qualified lookup:
bar1() : bar1<t>::base() {} bar1() : bar1::base() { } or not rely on injected-class-name of base:
bar1() : base<t>() { } vs wrong in accepting bar1. bar2 ok, if more verbose strictly possible. nothing wrong that.
worth noting if base weren't dependent, still use injected-class-name if template:
template <class t> struct base { }; struct derived : base<int> { derived() : base() { } // ok, lookup finds base<int>::base };
Comments
Post a Comment