2015-01-11 2 views
-1

막대의 클래스 멤버 인 std :: unique_ptr을 인쇄하고 싶습니다. 그러나 다음 코드는 내 의견을 에 표시하지 않습니다. < < bar.foo_unique(); 내 foo_unique() 접근자를 변경해야한다고 생각하지만 어떻게해야할지 모르겠다.ostream : std :: unique_ptr 클래스 멤버

#include <iostream> 
#include <memory> 
class Foo 
{ 
public: 
    Foo() : n_(1) {} 
    int n() const { return n_; } 

private: 
    int n_; 
}; 

std::ostream& operator<< (std::ostream& stream, const Foo& foo); 

std::ostream& operator<< (std::ostream& stream, const Foo& foo) 
{ 
    stream << foo.n(); 
    return stream; 
} 

class Bar 
{ 
public: 
    Bar() : m_(2), foo_(), foo_unique_(std::make_unique<Foo>()) {} 
    int m() const { return m_; } 
    const Foo& foo() const { return foo_; } 
    const std::unique_ptr<Foo>& foo_unique() const { return foo_unique_; } // what to return here ? 
private: 
    int m_; 
    Foo foo_;       
    std::unique_ptr<Foo> foo_unique_; 
}; 

std::ostream& operator<< (std::ostream& stream, const Bar& bar); 

std::ostream& operator<< (std::ostream& stream, const Bar& bar) 
{ 
    stream << bar.m() << ","; 
    stream << bar.foo(); 
    // stream << bar.foo_unique(); // does not work !!! 
    return stream; 
} 

int main() 
{ 
    Bar bar; 
    std::cout << bar << std::endl; 
} 

어떻게 제대로 수행 할 수 있습니까?

편집 : 스트림 싶어요 < < bar.foo_unique(); 스트림과 같은 동작을한다. < < bar.foo();

+0

평판이 좋지 않은 경우 오류 설명을 제공하는 것은 좋지 않습니다! – gsamaras

+0

1)'const std :: unique_ptr & foo_unique() const'는 (정확히) 어떻게해야하나요? 'Foo const & foo() const' 외에 왜 필요합니까? 2)'stream << bar.foo_unique();는 무엇을해야합니까? – dyp

+0

정밀도가 부족한 죄송합니다. << bar.foo_unique(); stream << bar.foo();와 같은 동작을 가져야합니다. ! – coincoin

답변

8

std::unique_ptr<T>에 대한 출력 연산자가 정의되어 있지 않습니다. 조금 슬프지만 많은 C++ 클래스에는 출력 연산자가 부족합니다. 가장 쉬운 방법은 바로 포인터를 인쇄하는 것입니다 : 당신이 얻으려면

stream << bar.foo_unique().get(); 

를 실제로 인쇄 된 포인터를하거나 pointee 인쇄 얻을하려는 경우 포인터

stream << *bar.foo_unique(); 

역 참조 할 것입니다.

출력 연산자를 사용하려면 사용자 정의 형식 인 Foo을 가정하면 std::unique_ptr<Foo>을 사용하여 출력 연산자를 직접 만들 수 있습니다. Foo 정의된다으로 동일한 공간에 넣어 줄 :

std::ostream& operator<< (std::ostream& out, std::unique_ptr<Foo> const& foo) { 
    return out << *foo; // or foo.get()depending on what you want to get printed 
} 
+0

감사합니다 _ 스트림 << * bar.foo_unique(); _ 원하는 방식으로 작동합니다. 그러나 마지막 코드를 추가하면 _error : 'std :: ostream & _ – coincoin

+2

형식의 참조 초기화가 유효하지 않습니다.'를 잊어 버렸습니다. return 문은 다음과 같아야합니다.'return out << * foo;' – leemes

+0

@leemes : true - 테스트 코드가 아니라는 위험! 고쳐 주셔서 감사합니다! –

0

std::unique_ptr<T>는 결정되는 스트림 삽입 조작을 방해 T const&에 암시 적 변환이 없다. 여기 몇 가지 옵션이 있습니다. 첫 번째 옵션은 std::unique_ptr<T>operator<<, 그리고 T&에 하나를 재정의하는 것입니다. std::unique_ptr과 소유하지 않은 원시 포인터 또는 참조를 모두 사용하면 지루할 수 있습니다. 두 번째 옵션은 std::unique_ptr<T> 인스턴스를 처리하기 위해 operator<<의 단일 템플릿 버전을 제공 한 다음 T const&을 처리 할 개별 템플릿 버전을 제공하는 것입니다. 다음은이를 수행하는 방법의 예입니다.

std::ostream& operator<< (std::ostream& out, Foo const& arg) 
{ 
    // output stuff here 
    return out; 
} 

template<class T> 
std::ostream& operator<< (std::ostream& out, std::unique_ptr<T> const& arg) 
{ 
    return out << *arg; 
} 
+0

* "스트림 삽입 연산자가 추론되는 것을 방해합니다."* 템플릿 인수 공제 * 에서처럼 추론됩니다. – dyp

관련 문제