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