2017-11-23 15 views
2

안녕하세요, 나는 상속을 통해 간단한 광고 - 혼합 클래스에서 복잡한 개체를 구성하는 데 도움이 될 수있는 몇 가지 메타 프로그래밍 라이브러리를 제작하고 있습니다.중첩 템플릿 시퀀스 대신 매개 변수 팩을 사용할 수 있습니까?

예를 들어, 각각 하나의 속성을 나타내는 일련의 템플릿 클래스를 생성하는 몇 가지 메커니즘이 있습니다.

는 I`ve은 다음과 같습니다 최종 건설 절차에 온 :

class Car : public Position< Size< Color< BaseObj<Car> > > > {/*...*/}; 

와 나는 확실히 그것을 좋아하지 않아.
내가 이런 식으로 쓸 수 있도록 일부 처리 템플릿을 만들려고

(BaseObj 항상 순서에서 가장 내부 템플릿입니다) :

class Car : public Proc< Position, Size, Color, Car > {/*...*/}; 

하지만 성공을 얻지 않았다.

이러한 템플릿을 만들 수 있습니까?
이러한 중첩 된 템플릿 시퀀스와 동일한 효과를 낼 수있는 다른 의미있는 의미가 있습니까?

+1

나는 그것을 할 수 어쩌면 생각합니다. 그러나 당신이 이루고 싶은 것은 나에게 불분명하다. ('Position'에 대한 매개 변수 인 Size는 정말로 이상하다.) –

+0

우선 가장 간단한 방법으로 행에서 다른 클래스를 상속받을 수있는 클래스 집합이 필요합니다. 템플릿은 '너비가 아니라' '깊이있게'상속하는 방법 일뿐입니다.각 템플릿을 혼합 구성 요소로 간주하십시오 (순서는 중요하지 않음). – Gleb

답변

-2

편집 나는 그 질문을 오해 한 것으로 보인다. 재귀 적으로 특성을 중첩하는 대신 특성 목록을 사용하도록 디자인을 변경하고 싶다고 생각했습니다. 이제는 기존 디자인으로 귀결되는 목록을 작성할 수있는 드롭 인 대체품을 찾고 있다는 것을 이해합니다. 그러나 그것은 왜 그런 디자인을 고수하고 싶습니까? 어떤 목적을 위해 봉사합니까? 나는 그저 그런 이유가 있다고 가정하고 있습니다. 이전에는 가변성 템플릿을 사용할 수 없었습니다.

내 대답은 여전히 ​​실행 가능하다고 생각하지만 위치, 크기, 색상 등의 현재 구현을 변경해야합니다. 그런 것들이하는 일에 대한 더 명확한 설명을 제공하기 전까지는 실제로 제안 할 수 없습니다.

올드 대답 : 당신이 앞에 CRTP -argument을 넣으면

글쎄, 그것은 좀 더 쉽게 될 것이다.

template<class S, class... P> 
class Proc : public P... 
{ 
    // ... 
}; 

class Car : public Proc<Car, Position, Size, Color> {/*...*/}; 
+1

'Car','Position '등이 타입이라면 작동 할 것이지만 템플릿이기 때문에 작동하지 않을 것입니다. – SirGuy

+0

그들은 다르게 구현하고 싶었던 템플릿 재귀를 사용하기 때문에 템플릿 일뿐입니다. 그는 그러한 것들이 무엇인지 * 정의하지 않았습니다 *. – oisyn

+0

수정 * 나는 그가 다르게 구현하고 싶다고 생각했다. – oisyn

5

그래서, 당신이 원하는 ...

nest<A, B, C, D>::type<E> 

이 ... 될 ...

A<B<C<D<E>>>> 

이것은 재귀의 일이다.


template <template <typename> typename...> 
struct nest; 

template <template <typename> typename First, 
      template <typename> typename... Rest> 
struct nest<First, Rest...> 
{ 
    template <typename Leaf> 
    using type = First<typename nest<Rest...>::template type<Leaf>>; 
}; 

template <template <typename> typename Last> 
struct nest<Last> 
{ 
    template <typename Leaf> 
    using type = Last<Leaf>; 
}; 

사용 예 :

template <typename> struct A { }; 
template <typename> struct B { }; 
template <typename> struct C { }; 
template <typename> struct D { }; 
struct E { }; 

int main() 
{ 
    static_assert(std::is_same_v< 
     typename nest<A, B, C, D>::template type<E>, 
     A<B<C<D<E>>>> 
    >); 
} 

live example on wandbox.org

+1

'static_assert'에'typename'과'template' 키워드가 필요하지 않습니다. 의존 키워드가 아닙니다. – SirGuy

+2

@SirGuy 충분한 템플릿을 다룬 후에는 잊어 버리십시오.) –

+0

고마워요! 나는 당신의 공사에 꽤 가깝지만 아직 효과가 없을 것입니다. – Gleb