타이핑리스트를 사용하는 방법
-
05-09-2019 - |
문제
나는 'Modern C ++ Design'의 타이틀리스트에 대해 읽었으며 유형을위한 일종의 연합으로 이해했습니다. 타이프리스트에 다른 비 관련 유형을 배치함으로써 상속없이 한 번에 둘 이상의 유형을 나타내는 데 사용할 수 있습니다. 나는 원시 유형의 일부 간단한 기능으로 타이틀리스트를 테스트했지만 그 중 어느 것도 작동하지 못했습니다.
누군가가 내 유형의 유형이 옳은지 말해 줄 수 있고 매일 평균 코드에서 타이틀리스트를 사용하는 방법을 간단한 실제 예를 들어 줄 수 있습니까? 미리 감사드립니다.
BTW, 나는 Windows and Visual Studio 2005와 그 컴파일러를 사용하고 있습니다.
편집 : 내 예제가 사라졌습니다. vs에서 샌드 박스 프로젝트를 사용하여 이러한 것들을 테스트합니다. 그러나 Dobbs 튜토리얼의 코드와 비슷했습니다.
void SomeOperation(DocumentItem* p)
{
if (TextArea* pTextArea = dynamic_cast<TextArea*>(p))
{
... operate on a TextArea object ...
}
else if (VectorGraphics* pVectorGraphics =
dynamic_cast<VectorGraphics*>(p))
{
... operate on a VectorGraphics object ...
}
else if (Bitmap* pBitmap = dynamic_cast<Bitmap*>(p))
{
... operate on a Bitmap object ...
}
else
{
throw "Unknown type passed";
}
}
이것은 작동하지만 동일하게 할 수있는 상속에 대한 이점은 보이지 않습니다. 그리고 동적 캐스트는 원시 유형에서 작동하지 않습니다. 다음과 같은 반환 값으로 사용할 수 있습니까?
typedef Typelist<int, string> mylist
mylist myfunction() {
if(foo == bar)
return 5;
return "five";
}
해결책
타이피리스트는 일반적인 컴파일 타임 유형 컬렉션입니다. Dynamic_cast를 사용하는 경우 정적 인 컴파일 시간 개념이기 때문에 요점이 없어야합니다.
이것은 작동하지만 동일하게 할 수있는 상속에 대한 이점은 보이지 않습니다.
기존 유형의 상속은 원하는대로 상속 할 수 없습니다. 이 기존 유형은 내장형 유형이거나 라이브러리의 유형 일 수 있기 때문에 이것은 단순히 실현할 수 없습니다. 타이틀리스트를 유형 목록 (예 : std :: pair)의 확장으로 생각하십시오 (단지 2 대신).
타이피리스트는 인수 세트를 기능으로 전달할 수있는 시설을 만드는 데 사용될 수 있습니다. 이것은 튜플에 보관 된 객체의 유형을 정의하는 타이프리스트와 함께 Tupe (또 다른 하나)에 제공된 인수와 함께 5 개의 매개 변수 (현대 C ++ 디자인의 또 다른 개념)의 일반화 된 기능을 호출하는 코드입니다.
//functor is just a holder of a pointer to method and a pointer to object to call this
//method on; (in case you are unfamiliar with a concept)
template<class R, class t0, class t1, class t2, class t3, class t4>
R call(Loki::Functor<R,LOKI_TYPELIST_5(t0, t1, t2, t3, t4
)> func,
Loki::Tuple<LOKI_TYPELIST_5(t0, t1, t2, t3, t4)> tuple)
{
///note how you access fields
return func(Loki::Field<0>(tuple), Loki::Field<1>(tuple),
Loki::Field<2>(tuple), Loki::Field<3>(tuple),
Loki::Field<4>(tuple));
}
//this uses the example code
#include<iostream>
using namespace std;
int foo(ostream* c,int h,float z, string s,int g)
{
(*c)<<h<<z<<s<<g<<endl;
return h+1
}
int main(int argc,char**argv)
{
Loki::Functor<int,LOKI_TYPELIST_5(ostream*, int, float, string, int)> f=foo;
//(...)
//pass functor f around
//(...)
//create a set of arguments
Loki::Tuple<LOKI_TYPELIST_5(ostream*, int, float, string, int)> tu;
Field<0>(tu)=&cout;
Field<1>(tu)=5;
Field<2>(tu)=0.9;
Field<3>(tu)=string("blahblah");
Field<4>(tu)=77;
//(...)
//pass tuple tu around, possibly save it in a data structure or make many
//specialized copies of it, or just create a memento of a call, such that
//you can make "undo" in your application; note that without the typelist
//you would need to create a struct type to store any set of arguments;
//(...)
//call functor f with the tuple tu
call(f,tu);
}
튜플이나 함수와 같은 다른 개념에서만 타이핑리스트가 유용하기 시작합니다. 또한 프로젝트에서 약 2 년 동안 Loki를 경험 해 왔으며 템플릿 코드 (많은 것)로 인해 디버그 버전의 실행 파일 크기는 큰 경향이 있습니다 (내 레코드는 35MB 정도). 또한 편집 속도에 약간의 타격이있었습니다. 또한 C ++ 0X에는 아마도 동등한 메커니즘이 포함될 것임을 기억하십시오. 결론 : 필요하지 않은 경우 타이피리스트를 사용하지 마십시오.
다른 팁
타이피리스트는 컴파일 프로세스의 일부로 "실행"하는 메타 프로그램에 "매개 변수 목록"을 전달하는 방법입니다.
따라서, 그들은 일종의 "Union"유형을 생성하는 데 사용할 수 있지만 이것은 단 하나의 가능한 사용 일뿐입니다.
"Real-World"예 : 우리는 COM 객체를 구현할 때 "QueryInterface"메소드를 자동으로 생성하는 방법으로 TypLists를 사용했습니다. 혜성 도서관.
다음과 같이 코드를 쓸 수있었습니다.
class Dog : public implement_qi<make_list<IAnimal, INoisy, IPersistStream> >
{
// The implement_qi template has provided
// an implementation of COM's QueryInterface method for us without
// having to write an ugly ATL "message map" or use any Macros.
...
}
이 예에서 "make_list"는 "유형 목록"을 생성하는 데 사용되는 템플릿으로, 구현 _QI 템플릿이 "열거"할 수 있습니다. 적절한 QueryInterface 코드를 생성하십시오.