나는 개인적으로 정말 Boost.Fusion을 주셔서 감사합니다, 그것은 아주 쉽게 유형을 혼합 할 수 있기 때문에) 여기
, 나는 boost::fusion::map
를 사용합니다.
데이터를 저장하는 데 사용되는 태그 유형 (컴파일 용도로만 사용되는 유형)과 실제 유형의 조합을 사용해야합니다.
의 우리의 태그를 정의 할 수 있습니다 : 그런 다음 태그 목록을 받아 같은 적절한 boost::fusion::map
GENERATE_MY_TYPE(TypeName, (a_tag)(b_tag)(c_tag)(d_tag));
// For information: (a_tag)(b_tag)(c_tag)(d_tag) is called a sequence in PP
유형은한다 무언가를 생성 Boost.Preprocessor를 사용하여 매크로를 기록 할 수
class a_tag { typedef bool type; };
class b_tag { typedef int type; };
class c_tag { typedef float type; };
class d_tag { typedef double type; };
을 :
typedef boost::fusion::map<
std::pair<a_tag, a_tag::type>,
std::pair<b_tag, b_tag::type>,
std::pair<c_tag, c_tag::type>,
std::pair<d_tag, d_tag::type>
> TypeName;
또는 boost :: fusion :: map을 구현 세부 사항으로 말하면 다음과 같습니다.
// defined once
template <class Vector>
struct TemplateType
{
typedef Vector tags_type;
typedef detail::deduce<Vector>::type data_type
// which for Vector = boost::mpl::vector<a_tag, b_tag, c_tag, d_tag> should be
// typedef boost::fusion::map<
// std::pair<a_tag, a_tag::type>,
// std::pair<b_tag, b_tag::type>,
// std::pair<c_tag, c_tag::type>,
// std::pair<d_tag, d_tag::type>
// > data_type;
data_type m_data;
template <class T>
boost::fusion::result_of::at<T, data_type> at()
{
return boost::fusion::at<T>(m_data);
}
};
// Generated by the macro, filling boost::mpl::vector by iteration
// the sequence
typedef TemplateType< boost::mpl::vector<a_tag, b_tag, c_tag, d_tag> > TypeName;
그런 다음 태그의 하위 집합에서 변환 트릭을 제공하기 만하면됩니다. 전체 하위 집합 만 있으면됩니다. 채우기
template <class Vector>
TypeName toTypeName(TemplateType<Vector> const& arg)
{
TypeName result;
result.fill(arg);
return result;
}
는 다음과 같이 정의되고 :
namespace detail
{
class NoAssign
{
template <class Pair, class TT> static Do(Pair const&, TTconst&) { }
};
class Assign
{
template <class Pair, class TT>
static Do(Pair& p, TTconst& tt)
{
p.second = tt.at<typename Pair::first_type>();
};
};
template <class Vector>
class Filler
{
public:
Filler(TemplateType<Vector> const& ref): m_ref(ref) {}
template <class T, class U>
void operator()(std::pair<T,U>& p) const
{
typedef typename boost::mpl::find<T,Vector>::type it;
typedef typename boost::mpl::end<Vector>::type end;
typedef typename boost::mpl::if< boost::same_type<it,end>, NoAssign, Assign> assign;
assign::Do(p, m_ref);
}
private:
TemplateType<Vector> const& m_ref;
};
}
template <class Vector>
template <class OV>
void TemplateType<Vector>::fill<OV>(TemplateType<OV> const& rhs)
{
boost::fusion::for_each(m_data, detail::Filler<OV>(rhs));
}
내가 그 문제를 사랑하지만, 물론 일부 템플릿 클래스/메소드를 생성하는 메타 템플릿 Progamming 및 전처리를 모두 사용하도록 강요하고 ... 의미 일부 오랜 해결책과 두통이 있습니다. 그러나 일단 구문이 실제로 (사용자에 대한) 깔끔한 수 있습니다.
아니요. 이렇게하면 해결하려는 문제를 설명하는 것이 좋습니다. –
속성을 공개하는 것은 나쁜 생각이라는 점에 유의하십시오. 그들을 비공개로 만들고 세터와 게터를 추가하십시오. –
닐 : 설명을 위해 제 편집문을 읽으십시오 – genesys