2016-11-18 4 views
1

나는 아래처럼 가변 인자 템플릿 멤버 함수 (foo)를 가진 클래스를 가지고있다. 이 아이디어는 매개 변수의 모든 double을 건너 뛰고 사용자가 제공 한 인수로 객체를 할당하는 것입니다.가변 인자 템플릿 함수 오버로딩

template <class T> 
    class Var { 
    public: 

     template <typename U, typename ...Args> 
     int foo(int index, Args... args) 
     { 
      T* p = new U(args...); 
      // save in an array at index 'index' 
     } 

     template <typename U, typename ...Args> 
     int foo (double index, Args... args) 
     { 
      // do something with index and skip it 
      return foo<U>(args...); 
     } 
    }; 

    class A { 
    public: 
     A (int i, const char *p) 
     { 

     } 
    }; 

    int main() 
    { 
     Var<A> var; 

     var.foo<A>(1.0, 2, 3, "Okay"); 
    } 

이제이 문제가 발생합니다.

  • 건너 뛰기의 배수를 몇 개 적용하십시오. 예 : 2 배로 건너 뛰고 다음 인수는 int 여야합니다. 그렇지 않으면 오류가 발생합니다.

  • 'double'대신 'int'를 사용하십시오. 그래서 우리는 2 개의 정수를 건너 뛸 것입니다. 다음 색인은 배열에 대한 '색인'이됩니다.

기본적으로 아니오를 전달하고 싶습니다. 클래스 템플릿 매개 변수로 건너 뛸 ints.

template <class T, int SKIP> 
class Var { 

그리고 건너 뛸 정수를 결정하기 위해 SKIP을 사용하십시오.

이렇게 할 수 있습니까? 당신의 SKIP 목표에 대한

+0

나는 그와 비슷한 것을 할 수 있다고 생각하지만, 결과 코드는 오히려 못 생기고 뒤얽힌 것 같습니다. 이것은 학문적 인 질문 일 뿐이며 해결하고자하는 실질적인 문제가 있습니까? 당신이 정확한 행동을 얻으려고하는 것과 같은 정확한 질문을하면 도움이 될 것입니다. –

+0

이것은 좀 더 학문적입니다. Novelocrat에서 제안한 계획에 따라 아래에 추가 한 솔루션이 있습니다. 내 코드 기반에는 유형 OR 유형 및 하위 유형에 따라 객체를 저장해야하는 실제 사용 사례가있었습니다. 따라서 조회 함수는 (int 유형) 또는 (int 유형, int 부속 유형)입니다. 그러나 나는이 제도를 사용하지 않았다. 서로 다른 인수 집합을 사용하여 동일한 함수 (함수 이름)를 리디렉션 한 2 개의 특수 클래스를 사용하는보다 간단한 솔루션을 생각해 냈습니다. – MGH

답변

1

그래서 이것이 내가 Novelocrat에서 힌트를 얻었습니다. 단지 붙여 넣기 만하면됩니다.

template <class T, int SKIP> 
class FooHelper { 
public: 

    template <typename U, typename ...Args> 
    static int foo_helper(int index, Args... args) 
    { 
     FooHelper<T, SKIP-1>::foo_helper<U>(args...); 
     return 0; 
    } 
}; 

template <class T> 
class FooHelper<T, 0> { 
public: 

    template <typename U, typename ...Args> 
    static int foo_helper (Args... args) 
    { 
     auto p = new U(args...); 
     return 0; 
    } 
}; 

template <class T, int SKIP> 
class Var { 
public: 

    template <typename U, typename ...Args> 
    int foo(Args ...args) 
    { 
     FooHelper<T, SKIP>::foo_helper<U>(args...); 
     return 0; 
    } 
}; 
1

, 당신은 이런 식으로 뭔가를 할 수 :

template <typename U, typename ...Args> 
int foo(Args ...args) { 
    return foo_helper<U, 0>(std::forward(args)); 
} 

template <typename U, int I, typename ...Args> 
int foo_helper(int index, Args ...args) { 
    return foo_helper<U, I+1>(std::forward(args)); 
} 

template <typename U, typename ...Args> 
int foo_helper<U, SKIP, Args...>(int index, Args ...args) { 
    blah = new U(std::forward(args)); 
    return foobar; 
} 

은 기본적으로 대상까지 계산하고 도달 할 때까지 인수를 벗겨 방법이있다. 목표 값을 전문화하십시오. 또한

하지 당신은 아마 인수가 참조를 유지하기 forward, 원하는거야 등

나는 C++ (14)이 쉽게 몇 가지를 만들 수도 있습니다 생각하지만, 나는 새로운 템플릿을 충분히 익숙하지 해요 이를 해결하기위한 메타 프로그래밍 기술.

+0

답변 해 주셔서 감사합니다. 그러나 여기서 함수 템플릿의 부분적 특수화를 수행하지 않습니까? 그것은 컴파일되지 않습니다. 그러나 템플릿 클래스 전문화와 동일한 기술이 작동합니다. – MGH

+0

맞아요, 그것은 함수 템플릿의 부분 전문화입니다. 나는 위의 코드를 직접 생각하거나 테스트하지 않았습니다. 하지만 네, 항상 작동하도록 클래스 템플릿에 포함될 수 있습니다. – Novelocrat