2017-04-07 13 views
0

C++에서 다음과 같은 것이 가능한지 알고 싶습니다. 키가 std::string이고 값이 함수 포인터 인 데이터 멤버 인 std::map을 저장할 클래스를 생성해야합니다. 것은 내가이 함수 포인터들이 양식의 기능을 가리키는 즉 인수의 임의의 수를 받아들이는 기능을 가리켜 야한다는 의미에서 가변되고 싶어한다는 것입니다가변 포인터 함수를 멤버로 사용하여 클래스를 생성하는 방법은 무엇입니까?

template<class... Args> f(Args...);

중요한 비트입니다 I 내 클래스의 주어진 인스턴스의지도에서 다른 함수 포인터에 대해 다른 인수를 가질 수 있기를 원합니다. 예를 들어, 클래스의 객체를 만들고지도에 두 쌍을 포함시킬 수 있습니다. 하나는 (double, int)을 인수로 갖는 함수에 해당하고 다른 하나는 (std::vector, int, int)을 인수로 갖는 것입니다. 그리고 나는이 일반적인 것을 만들 수 있기를 원한다. 아마도지도에 새로운 요소를 추가 할 수 있기를 원한다. (비록 내가 컴파일 타임에만 이것을 할 것이지만, 여전히 코드를 작성할 필요가있다. 다른 파일/클라이언트에서 새 요소를 추가하려는 이후 유형에 대해 알지 못하는 클래스).

이것을 구현하는 가장 좋은 방법은 무엇입니까? 당신이, 당신이 실제로 할 수 캔트 말을 모든 사람들을 위해

+1

어떻게 맵에서 함수를 호출하겠습니까? 대부분의 솔루션은 모든 종류의 컴파일 타임 유형 안전을 떨어 뜨립니다. 'std :: any'를 사용하여 함수 포인터를 저장할 수 있습니까? –

+1

소리가 유형 삭제 작업과 같습니다. –

+0

'f '를 함수 포인터로 변환하면 고정 된 수의 매개 변수와 유형을 가진 구체적인 함수입니다. 템플릿을 저장할 수 없습니다. – nwp

답변

0

, 꽤 아니다 :

이는 MOC 도구의 출력에 들어있는 예제 코드, 정확히 않습니다 : 그것은 함수의 임의의 양을 저장/방법 임의의 수의 인수가있는 포인터.

가장 쉬운 해결책 : Qt의 moc 도구를 사용하여 생성하십시오. Qt를 사용할 수 없거나 사용하지 않으려는 경우 아래 코드를 통해이를 달성하는 방법을 계속 분석 할 수 있습니다.

int AtCore::qt_metacall(QMetaObject::Call _c, int _id, void **_a) 
{ 
    _id = QObject::qt_metacall(_c, _id, _a); 
    if (_id < 0) 
     return _id; 
    if (_c == QMetaObject::InvokeMetaMethod) { 
     if (_id < 25) 
      qt_static_metacall(this, _c, _id, _a); 
     _id -= 25; 
    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { 
     if (_id < 25) 
      *reinterpret_cast<int*>(_a[0]) = -1; 
     _id -= 25; 
    } 
    return _id; 
} 


void AtCore::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) 
{ 
    if (_c == QMetaObject::InvokeMetaMethod) { 
     AtCore *_t = static_cast<AtCore *>(_o); 
     Q_UNUSED(_t) 
     switch (_id) { 
     case 0: _t->printProgressChanged((*reinterpret_cast< const float(*)>(_a[1]))); break; 
     case 1: _t->receivedMessage((*reinterpret_cast< const QByteArray(*)>(_a[1]))); break; 
     case 2: _t->stateChanged((*reinterpret_cast< PrinterState(*)>(_a[1]))); break; 
     case 3: _t->print((*reinterpret_cast< const QString(*)>(_a[1]))); break; 
     case 4: _t->stop(); break; 
     case 5: _t->pause((*reinterpret_cast< const QString(*)>(_a[1]))); break; 
     case 6: _t->resume(); break; 
     case 7: _t->home((*reinterpret_cast< uchar(*)>(_a[1]))); break; 
     case 8: _t->home(); break; 
     case 9: _t->setExtruderTemp((*reinterpret_cast< uint(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break; 
     case 10: _t->setExtruderTemp((*reinterpret_cast< uint(*)>(_a[1]))); break; 
     case 11: _t->setExtruderTemp(); break; 
     case 12: _t->move((*reinterpret_cast< uchar(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break; 
     case 13: _t->setBedTemp((*reinterpret_cast< uint(*)>(_a[1]))); break; 
     case 14: _t->setBedTemp(); break; 
     case 15: _t->setFanSpeed((*reinterpret_cast< uint(*)>(_a[1])),(*reinterpret_cast< uint(*)>(_a[2]))); break; 
     case 16: _t->setFanSpeed((*reinterpret_cast< uint(*)>(_a[1]))); break; 
     case 17: _t->setFanSpeed(); break; 
     case 18: _t->setAbsolutePosition(); break; 
     case 19: _t->setRelativePosition(); break; 
     case 20: _t->setPrinterSpeed((*reinterpret_cast< uint(*)>(_a[1]))); break; 
     case 21: _t->setPrinterSpeed(); break; 
     case 22: _t->setFlowRate((*reinterpret_cast< uint(*)>(_a[1]))); break; 
     case 23: _t->setFlowRate(); break; 
     case 24: _t->close(); break; 
     default: ; 
     } 
    } else if (_c == QMetaObject::IndexOfMethod) { 
     int *result = reinterpret_cast<int *>(_a[0]); 
     void **func = reinterpret_cast<void **>(_a[1]); 
     { 
      typedef void (AtCore::*_t)(const float &); 
      if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&AtCore::printProgressChanged)) { 
       *result = 0; 
       return; 
      } 
     } 
     { 
      typedef void (AtCore::*_t)(const QByteArray &); 
      if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&AtCore::receivedMessage)) { 
       *result = 1; 
       return; 
      } 
     } 
     { 
      typedef void (AtCore::*_t)(PrinterState); 
      if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&AtCore::stateChanged)) { 
       *result = 2; 
       return; 
      } 
     } 
    } 
}