templated conversion constructor fails to access protected data members

喜你入骨 提交于 2019-12-22 01:14:29

问题


I have a templated class Rect with conversion constructor which allows conversion between Rect to Rect and vice a versa. But when compiling the code, the compiler gives an error stating the constructor can't access the protected members of the class. Here is code:

#include <iostream>
#include <list>
#include <algorithm>

using namespace std;

template< typename T >
class Rect{
protected:
  T width, height;
public:
  Rect(T a, T b){
    width = a;
    height = b;
  }
  template< typename U >
  Rect(Rect<U> const &r){
    width = r.width;
    height = r.height;
  }
  int area(){
    return width*height;
  }
};

int main(){
  Rect<int> a(3,4);
  Rect<float> b(a);
  cout<<b.area()<<endl;
}

And here is the compilation error:

test.cpp: In constructor ‘Rect<T>::Rect(const Rect<U>&) [with U = int, T = float]’:
test.cpp:28:18:   instantiated from here
test.cpp:10:7: error: ‘int Rect<int>::width’ is protected
test.cpp:18:5: error: within this context
test.cpp:10:14: error: ‘int Rect<int>::height’ is protected
test.cpp:19:5: error: within this context

I want to solve this problem without using template specialization and making friend classes. As far as I know you can't declare constructors as friends. Any ideas?

Edit: I have made corrections to semantics. So the constructor I am trying to build is really a conversion constructor.

Edit2: Corrected the program.


回答1:


As K-ballo mentioned, Rect<int> and Rect<float> are different types, and do not have access to each others' private and protected members. You can explicitly allow this by adding the following template friend declaration to your class (like so):

template <typename U> friend class Rect;

Semantically, this means "for any type U, give the class Rect<U> access to my private and protected members" -- it is an outgoing permission grant from every Rect instantiation to every other Rect instantiation.

Note that this won't be necessary if you add accessors for width and height (as K-ballo suggests) -- then you can just use those accessors in the conversion constructor and forgo the friend definition entirely. I would prefer his solution over mine; I give mine merely as another possible option and to introduce to you a concept (friends, and specifically template friends) that you might not be familiar with.




回答2:


First thing you should know is that a template constructor is never a copy constructor. Second thing is that Rect<T> and Rect<U> where T != U are different unrelated classes, as unrelated as a std::string and an std::vector.

You should offer some way to access width and height, and your conversion constructors should use such access methods to create the new Rect.



来源:https://stackoverflow.com/questions/11001480/templated-conversion-constructor-fails-to-access-protected-data-members

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!