c++ template template : cannot access private member -
i'm trying work template template parameters in c++, famous stack example :
however acompilation error in code below. understanding 'stack<t2, cont2>'
, 'stack<t, cont>'
same class 'container' accecible in 'stack<t, cont>::operator = ( const stack<t2, cont2>& rhs )'
could me? there specific should pay attention when working template template parameters?
template <typename t, template < typename elem, typename alloc = std::allocator< elem > > class cont = std::deque > class stack { cont<t> container ; public : stack() {} ; template <typename t2> void push_back ( const t2& elem ) ; bool isempty (void ) const ; template <typename t2, template < typename elem2, typename = std::allocator< elem2 > > class cont2 > stack<t, cont>& operator = (const stack<t2,cont2>& rhs ) ; void push_back (t const& elem ) { container.push_back (elem) ; }; t operator [] (size_t ) const ; t& operator [] ( size_t ) ; }; template <typename t, template <typename elem, typename alloc > class cont > t stack<t, cont>::operator [] (size_t ) const { return container [i] ; } template <typename t, template <typename elem, typename alloc > class cont > t& stack<t, cont>::operator[] ( size_t ) { return container [i] ; } template <typename t, template <typename elem, typename alloc > class cont > template <typename t2, template < typename , typename > class cont2 > stack<t, cont>& stack<t, cont>::operator = ( const stack<t2, cont2>& rhs ) { if ( this->container != rhs.container ) // error !!! { if ( this->container.size() == 0 ) { ( size_t = 0 ; < rhs.container.size() ; ++i ) { (*this).container.push_back( (t) rhs[i] ) ; } } else { ( size_t = 0 ; < this->container.size() ; ++i ) { (*this)[i] = rhs[i] ; } } } return *this ; } int main() { stack<int> stk ; stack<double> stkd ; stk.push_back(10) ; stk.push_back(5) ; stkd = stk ; int st = stk[1] ; return 0; }
the compilation error :
>e:\project2\project2\source.cpp(46): error c2248: 'stack<t>::container' : cannot access private member declared in class 'stack<t>' 1> 1> [ 1> t=int 1> ] 1> e:\project2\project2\source.cpp(12) : see declaration of 'stack<t>::container' 1> 1> [ 1> t=int 1> ] 1> e:\project2\project2\source.cpp(75) : see reference function template instantiation 'stack<t> &stack<t>::operator =<int,std::deque>(const stack<int> &)' being compiled 1> 1> [ 1> t=double 1> ] 1> e:\project2\project2\source.cpp(75) : see reference function template instantiation 'stack<t> &stack<t>::operator =<int,std::deque>(const stack<int> &)' being compiled 1> 1> [ 1> t=double 1> ]
a template blueprint compiler uses construct actual classes. whenever use template class specific parameter compiler creates class based on provided blueprint.
let's check out (extremely simplified) example:
template < typename t > class test { t member: };
when create test<int>
, test<double>
compiler generate 2 classes these:
class test/* information comes here, compiler can differentiate different test classes */ { int member; }; class test/* again additional information */ { double member; };
although quite similar, not same. same thing applies stack
. stkd
, stk
have different types , can therefore not assigned 1 another.
to fix can make every compiler generated instance of template friend of each other so:
template <typename t, template < typename elem, typename alloc = std::allocator< elem > > class cont = std::deque > class stack { /* ... */ public : /* ... */ template<class other, template < typename elem, typename allod = std::allocator< elem > > class cont > friend class stack; /* ... */ };
note won't allow compare different containers need find way prevent self assignments (if here has idea feel free add it). here modified assignment operator:
template <typename t, template <typename elem, typename alloc > class cont > template <typename t2, template < typename , typename > class cont2 > stack<t, cont>& stack<t, cont>::operator = ( const stack<t2, cont2>& rhs ) { /* self assignment check needed */ { if ( this->container.size() == 0 ) { ( size_t = 0 ; < rhs.container.size() ; ++i ) { (*this).container.push_back( (t) rhs[i] ) ; } } else { ( size_t = 0 ; < this->container.size() ; ++i ) { (*this)[i] = rhs[i] ; } } } return *this ; }
wiki
Comments
Post a Comment