현재 begin()
및 end()
을 포함한 몇 가지 가상 메소드를 제공하는 인터페이스 (다음 예에서는 Base
)를 설계 중입니다. 이 두 메소드는 클래스와 같은 다른 콜렉션과 같이 대응하는 반복자를 리턴한다. 파생 클래스는 이러한 메서드를 구현하고 iterator의 특정 구현을 반환해야합니다.기본 클래스의 기본 이터레이터 설계
다음은 (단순화 된) 예제는 boost::transform_iterator
을 사용하여 개인 내부 정수 목록을 변환하는 파생 클래스를 보여줍니다. 이 구현은 실제로 반복되는 "물건"이 다른 것일 수 있다는 반복자의 예일뿐입니다.
예제가 작동하지만 문제가 하나 있습니다. main()
의 오브젝트 유형은 사용 된 반복자가 TransformIterator
유형이라는 사실을 숨기지 않습니다. 기본 클래스는 모든 플러그인이 공유 라이브러리 인 일종의 플러그인 아키텍처에서 사용됩니다. 플러그인은 사용되는 반복자의 유형을 알지 않아야하며 추상 인터페이스에만 의존해야합니다. 이것을 할 수있는 방법이 있습니까?
#include <boost/iterator/transform_iterator.hpp>
#include <iostream>
#include <string>
#include <vector>
template<class Iterator>
class Base
{
public:
virtual Iterator begin() = 0;
virtual Iterator end() = 0;
};
struct toString
{
std::string operator()(int number) const
{
return std::to_string(number);
}
};
typedef boost::transform_iterator<toString, std::vector<int>::iterator> TransformIterator;
class Derived : public Base<TransformIterator>
{
public:
Derived() : ints{132, 3, 6451, 12, 5} {}
TransformIterator begin()
{
return boost::make_transform_iterator(ints.begin(), toString());
}
TransformIterator end()
{
return boost::make_transform_iterator(ints.end(), toString());
}
private:
std::vector<int> ints;
};
int main()
{
Base<TransformIterator>* obj = new Derived();
for(const auto& value : *obj)
{
std::cout << value.size() << std::endl;
}
return 0;
}
조금 더 배경 :이 특정 예는 구성 파일을 읽는 인터페이스를 기반으로합니다. 현재 YAML 파일에 대한 구현 만 제공 할 계획이지만 XML 또는 이전 학교 INI와 같은 다른 형식도 가능합니다. 따라서 공통 인터페이스.
아 이제 해결책을 찾지 못했습니다. 이 특별한 경우에는 가상 함수 호출이 문제가되어서는 안됩니다. 구성은 시작시 한 번 읽습니다. – tea2code
참고 : STL 알고리즘과 함께 사용하려면 추상 반복자에 대해 std :: iterator_traits를 전문화하거나 이미 적절한 전문화가 적용된 std :: iterator에서 파생 시키길 원할 것입니다. – heinrichj