2017-12-27 4 views
0

올바른 함수 템플릿을 추론하도록 컴파일러를 얻으려고합니다. 다음 코드 올바른 템플릿 기능이 추론은 ... 오버로드 된 함수 포인터를 오버로드 된 템플릿 함수의 인수로 전달합니다.

class TestBase{}; 

template <typename c, typename RT, typename T0> 
inline void CallF(RT(c::*M)(T0), TestBase* pObject, std::vector<OVariant> args) 
{ 
    //safely convert variant (implementations external to class) 
    T0 t0 = args[0].GetSafe<T0>(); 

    ((static_cast<c*>(pObject))->*M)(t0); 
} 

template <typename c, typename RT, typename T0, typename T1> 
inline void CallF(RT(c::*M)(T0, T1), TestBase* pObject, std::vector<OVariant> args) 
{ 
    //safely convert variant (implementations external to class) 
    T0 t0 = args[0].GetSafe<T0>(); 
    T1 t1 = args[1].GetSafe<T1>(); 

    ((static_cast<c*>(pObject))->*M)(t0, t1); 
} 

class Test : public TestBase 
{ 
public: 

    void F(s32 one) 
    { 
     std::cout << "one"; 
    } 

    struct Wrapped_F 
    { 
     //OVariant is my typical variant class 
     static void Call(TestBase* pObject, std::vector<OVariant> args) 
     { 
      ::CallF<Test>(&Test::F, pObject, args); 
     } 
    }; 
}; 

int main(int argc, char *argv[]) 
{ 
    Test t; 
    OVariant i(13); 
    std::vector<OVariant> args; 
    args.push_back(i); 

    t.Wrapped_F::Call(&t, args); 
} 

t.Wrapped_F :: 전화 (& t, 인수가) 올바른 F 함수를 호출을 감안할 때. 내가 테스트하는 오버로드 된 F 기능, 다음 (2 개 인수에 과부하)을 추가하는 경우 그러나, 나는 이것이 때문입니다 확신

void F(s32 one, s32 two) 
{ 
    std::cout << "two"; 
} 

(1 개 인수로 대신 올바른 F의) 호출됩니다 컴파일러가 추론 할만한 충분한 정보가 없다는 사실. 어떻게 컴파일러가 호출 할 오버로드 된 템플릿 함수를 추론 할 수 있습니까? 다음 의사 코드와 같은

뭔가

(? 알 수없는 유형의 몇 가지 인수 표시하기 위해)

static void Call(TestBase* pObject, std::vector<OVariant> args) 
{ 
    //Note: I won't know anything about the arguments to function F; I do know the size of the vector 
    switch (args.size()) 
    { 
    case 1:::CallF<Test,void,?>(&Test::F, pObject, args); 
    case 2:::CallF<Test,void,?,?>(&Test::F, pObject, args); 
    } 
} 

이 할 수있는 방법이 있나요를?

답변

1

컴파일러는 variant 클래스 내에 저장된 내용을 알 수있는 방법이 없습니다. 따라서 ?은 함수 유형 (매개 변수에서)에서 으로 추론 될 수 있습니다. 따라서 args.size()이 함수 매개 변수의 수와 일치하는지 확인하는 코드가 필요합니다. 다음을 수행하십시오 :

  • args.size()std::tuple<Args...>
  • 의 요소 튜플에 args 벡터 변환의 수와 같은
  • 확인하는 것이 Args...이 함수 타입에서 평가 std::tuple<Args...>을 만듭니다.
  • 사용 std::apply 내가 당신의 생각의 변화를 시도 튜플
+0

에서 인수 함수를 호출 (또는 자신을 다시 발명), 그러나 아주 잘 맞는 것 같지 않습니다. 호출 함수에서 함수 유형을 알 수없는 경우 std :: tuple을 만드는 방법은 입니까? OVariant :: GetSafe (T0 t0 = args [0] .GetSafe ();)를 호출 할 수있는 능력을 잃을까요? –