#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