2012-04-04 2 views
1

부스트 범위에는 쉼표 또는 공백으로 구분하여 쉽게 요소를 포함 할 수있는 기본 제공 방법이 있습니까?cout a boost :: elements of range

나는 루프를 걸고 따로 인쇄 할 수 있다는 것을 알고 있지만, 어떻게 든 스크립트 언어로 벡터를 인쇄하는 것과 같은 방식으로 만들어야한다.

부스트 :: 사본 (범위, ostream_iterator와 (COUT를, ""))

나에게 추한 외모 : 내가 본 예제 프로그램에서

은, 저자를 법원에 범위를 복사 . 이것은 관용적입니까?

EDIT : 표준 반복기의 솔루션도 사용할 수 있습니다.

는 EDIT2 :

cout << range; 

하지만 작품이라고 생각하지 않습니다 는 내가하고 싶은 것은 이것이다. 다양한 어댑터

cout << range.join(", "); 

혹은 : 그래서 내가 바라고있는 무슨이 (영감 파이썬) 같은 것입니다.

cout << (range | stringify(", ")); 

답변

4

나는 그것이 이제까지 정말/광택 완료 됐어요 생각하지 않는다, 그러나 그것은 Boost.Explore의 의도입니다.

개인적으로 저는 방금 std::copy에 익숙해졌습니다. 이런 종류의 경우에, infix_ostream_iterator은 때때로 도움이 될 수 있습니다. 이 같은 예를 들어 뭔가 : 약자로

#include <vector> 
#include <iostream> 
#include <algorithm> 
#include <iterator> 
#include "infix_iterator.h" 

template <typename T> 
std::ostream& operator<<(std::ostream &o, const std::vector<T>& v) { 
    o << "["; 
    std::copy(v.begin(), v.end(), infix_ostream_iterator<T>(o, ", ")); 
    o << "]"; 
    return o; 
} 

int main() { 

    std::vector<int> x; 

    for (int i=0; i<20; i+=2) 
     x.push_back(i); 

    std::cout << x << "\n"; 
    return 0; 
} 

, 이것은 operator<<이 벡터를 복용했지만, 대신 범위를 가지고있는 비교적 사소한 것입니다.

+0

감사합니다. STL과 부스트가 공통 컨테이너에 대해 이것을 정의하지 않는 특별한 이유는 무엇입니까? 나는이 방법에 대해 알고 있었지만 (늘리면 탐험에 대해 들어 본 적이 없다.), 더 숙련 된 방법이있을 때 언제나 좀 더러운 정의 도우미 기능을 느낀다. – Gurgeh

+0

@Gurgeh : 나는 완전히 확신하지 못합니다. 완전히 일반적인 경우, 문자열 입력 또는 출력과 같은 문제를 "처리"하려고 할 수 있습니다. 이는 문제가 될 수 있습니다. –

+0

그건별로 이유가되지 않습니다 (당연히 당신을 비난하는 것이 아닙니다).정상적인 상황에서는 오버로드 된 운영자가 올바른 순서로 해결되도록하는 것이 어렵지 않습니다. 그리고 무언가가 잘못 될 수있는 경우가 드물기 때문에 항상 표준 컨테이너마다 수동으로 정의 할 수 있습니다. 어쨌든 몇 시간 후에 더 좋은 것이 나오지 않으면 답을 고를 것입니다. 토론 해 주셔서 감사합니다! – Gurgeh

1

앞으로 반복 가능한 범위를 출력하는 일반 함수를 정의하고자 할 수 있습니다.

template<typename ForwardIter> 
std::string join(const ForwardIter& it1, const ForwardIter& it2, const std::string& separator=" ") { 
    if(it1 != it2) { 
     std::ostringstream s; 
     s << *it1; 
     for(ForwardIter i=it1+1; i!=it2; i++) s << separator << *i; 
     return s.str(); 
    } 
    else return ""; 
} 

template<typename Range> 
std::string join(const Range& r, const std::string& separator=" ") { return join(r.begin(), r.end(), separator); } 

이 함수는 문자열을 반환하고 이러한 각 요소의 간접 참조를 출력 할 수있는 등의리스트, 벡터 설정으로 어느 순방향 반복 가능한 범위를 취한다 : 여기에 사용되는() 함수 조인 ostream에 의해 개별적으로. 이 기능을, 당신은 그것을 좋아 사용할 수 있습니다

list<int> a = {1,2,3,4}; 
set<int> b = {4,3,2,1}; 
vector<int> c = {1,2,3,4}; 


cout << join(a) << endl; 
cout << join(b, ",") << endl; 
cout << join(c.begin(), c.begin()+2, "~") << endl; 

나는 당신이 그런 가입 또는 공동으로 유사한 이름으로 이름을 변경 할 수 있도록 조인() 이름이 일부 네임 스페이스와 충돌 할 수 있음을 기억하십시오. 또한 부스트를 사용하는 경우 r.begin() 대신 boost :: begin (r)을 사용하여 호환성을 향상시킬 수 있습니다.