문제

#include <iostream>

namespace outside {
  struct A { 
    int outer = 42; 

    friend void print(A const& a, std::ostream& os) 
    { os << "outside::A " << a.outer << '\n'; }
  };
  namespace inside {
    struct A : outside::A { 
      int inner = 24; 
      void print(std::ostream& os) { } // Added for extra difficulty
      friend void print(A const& a, std::ostream& os) { 
        // outside::A::print(a, os); // <- does not compile
        os << " inside::A " << a.inner << '\n'; 
      }
    };
  } // inside
} // outside

int main(int argc, char *argv[]) {
  outside::A a_outside;
  outside::inside::A a_inside;

  print(a_outside, std::cout);
  print(a_inside, std::cout);
}

Is there a way to qualify the print function so that both base and derived members are printed? I could move both the friend functions to their closest enclosing namespaces:

#include <iostream>

namespace outside {
  struct A { int outer = 42; };
  void print(A const& a, std::ostream& os) 
  { os << "outside::A " << a.outer << '\n'; }

  namespace inside {
    struct A : outside::A { 
      void print(std::ostream& os) { } // Added for extra difficulty
      int inner = 24;
    };
    void print(A const& a, std::ostream& os) { 

      outside::print(a, os); // <- works
      os << " inside::A " << a.inner << '\n'; 
    }
  } // inside
} // outside

int main(int argc, char *argv[]) {
  outside::A a_outside;
  outside::inside::A a_inside;

  print(a_outside, std::cout);
  print(a_inside, std::cout);
}

This works, here's the result:

outside::A 42 outside::A 42 inside::A 24

Can the same be achieved with the friend functions though? Maybe using using?

EDIT: inside::A::print(std::ostream&) defeats the static cast suggest below, https://stackoverflow.com/a/22585103/710408. Any other options?

도움이 되었습니까?

해결책

I find possible solution:

friend void print(A const& a, std::ostream& os) { 
    print(static_cast<const outside::A&>(a), os);
    os << " inside::A " << a.inner << '\n'; 
}

Some info why this dont work: https://stackoverflow.com/a/382077/1938348 Conclusion is simple when you define friend function in class body its invisible unless you use ADL. To made it work as you excepted you need change place of declaration:

namespace outside {
  struct A { 
    int outer = 42; 

    friend void print(A const& a, std::ostream& os);
  };
  void print(A const& a, std::ostream& os) {
    os << "outside::A " << a.outer << '\n';
  }
  namespace inside {
    struct A : outside::A { 
      int inner = 24; 

      friend void print(A const& a, std::ostream& os);
    };
    void print(A const& a, std::ostream& os) { 
      outside::print(a, os);
      os << " inside::A " << a.inner << '\n'; 
    }
  } // inside
} // outside

다른 팁

Do you mean:

  friend void print(A const& a, std::ostream& os) { 
    // outside::A::print(a, os);
    print(static_cast<const outside::A&>(a), os);
    os << " inside::A " << a.inner << '\n'; 
  }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top