c++ - Friend member function definition conflicts with in-class initializer -


i reading c++ primer , trapped same code in question (with little difference), question different. know there lot of similar questions, after searching around, seems no answer answer question.

at beginning, code worked fine when didn't add friend member function.

/* first class */ class screen { public:     using pos = std::string::size_type;     using content_type = char;      screen() = default;     screen(pos ht, pos wd, content_type c)         : height(ht), width(wd), contents(ht * wd, c) {}      // other inline functions omited.  private:     pos width = 0;     pos height = 0;     std::string contents; };  /* second class */ class window_mgr { public:     using screen_index = std::vector<screen>::size_type;  private:     std::vector<screen> screens{screen(24, 80, ' ')};  // use `screen` ctor }; 

then, want add friend member function clear. wrote 2 versions of code according code near page 281 in book. first version uses in-class initializer initialize vector data member of window_mgr, while second version uses constructor initializer list.

the first version (error) book wrote:

making member function friend requires careful structuring of our programs accommodate interdependencies among declarations , definitions. in example, must order our program follows:

  • first, define window_mgr class, declares, cannot define clear. screen must declared before clear can use members of screen.
  • next, define class screen, including friend declaration clear.
  • finally, define clear, can refer members in screen.
/* part 1, window_mgr.h */ class screen;  class window_mgr { public:     using screen_index = std::vector<screen>::size_type;     void clear(screen_index);  private:     std::vector<screen> screens{screen(24, 80, ' ')};  // error: no ctor `screen` };  /* part 2, screen.h */ class screen {     friend void window_mgr::clear(screen_index);  public:     using pos = std::string::size_type;     using content_type = char;      screen() = default;     screen(pos ht, pos wd, content_type c)         : height(ht), width(wd), contents(ht * wd, c) {}      // other inline functions omited.  private:     pos width = 0;     pos height = 0;     std::string contents; };  /* part 3, window_mgr.cpp */ void window_mgr::clear(screen_index i) {     screen &s = screens[i];     s.contents = std::string(s.height * s.width, ' '); } 

the second version (no error), inspired this answer:

/* part 1, window_mgr.h */ class screen;  class window_mgr { public:     using screen_index = std::vector<screen>::size_type;     void clear(screen_index);     window_mgr();  // add ctor declaration  private:     std::vector<screen> screens;  // remove in-class initializer };  /* part 2, screen.h */ class screen {     friend void window_mgr::clear(screen_index);  public:     using pos = std::string::size_type;     using content_type = char;      screen() = default;     screen(pos ht, pos wd, content_type c)         : height(ht), width(wd), contents(ht * wd, c) {}      // other inline functions omited.  private:     pos width = 0;     pos height = 0;     std::string contents; };  /* part 3, window_mgr.cpp */ window_mgr::window_mgr() : screens{screen(24, 80, ' ')} {}  // add ctor definition // because `screen` complete type, can use ctor  void window_mgr::clear(screen_index i) {     screen &s = screens[i];     s.contents = std::string(s.height * s.width, ' '); } 

note put 3 parts of code in single file convenience, can split 3 different files proper include guards , include header files.

i understand forward declaration , include guards, i'm not asking them, here questions.

  1. is constructor defined outside class window_mgr the way initialize data member screens if want use class screen directly (not pointer or reference)?

    i think in-class initializer cannot used in first version because screen incomplete type when ctor called.

  2. why incomplete type (screen) can used parameter vector template?

possible similar questions:

i trying seems little bit verbose, anyway reading , helping :)


Comments

Popular posts from this blog

c++ - llvm function pass ReplaceInstWithInst malloc -

Cross-Compiling Linux Kernel for Raspberry Pi - ${CCPREFIX}gcc -v does not work -

java.lang.NoClassDefFoundError When Creating New Android Project -