2016-09-18 1 views
-1

다음은 this 질문입니다. 나는 BaseSensor 클래스의 mixins에서 같은 이름의 모든 메소드를 호출하는 것과 관련된 일부 코드를 복사하여 붙여 넣는 것을 피하려고합니다. MAIN.CPP에 sensor.hpp sensor.t.hppC++ 용 템플릿 함수 이름을 가진 가변 템플릿들 012

template<typename ... SensorType> 
void BaseSensor<SensorType...>::update() 
{ 
    int arr[] = { (SensorType::update(), 0)..., 0 }; 
    (void)arr; 
} 

template<typename ... SensorType> 
void BaseSensor<SensorType...>::printStats() 
{ 
    int arr[] = { (SensorType::printStats(), 0)..., 0 }; 
    (void)arr; 
} 

struct EdgeSensor //a mixin 
{ 
    void update(){} 
    void printStats() {} 
}; 

struct TrendSensor //another mixin 
{ 
    void update(){} 
    void printStats() {} 
}; 

template<typename ... SensorType> 
class BaseSensor : public SensorType ... //to my BaseSensor class 
{ 
    void update() /*{ what goes in here??? }*/ 
    void printStats() /*{ what goes in here??? }*/ 
}; 

int main(int , const char **) 
{ 
    { 
     BaseSensor<EdgeSensor,TrendSensor> ets; 
     ets.update(); 
     ets.printStats(); 
    } 
    { 
     BaseSensor<EdgeSensor> ets; 
     ets.update(); 
     ets.printStats(); 
    } 
} 

상기 코드는 모든 유지 mixin의 update()에서 실행 모든 mixins에서 모든 printStats()을 실행하기 전에 계속하십시오. 예를 들어

:이 BaseSensor::update()BaseSensor::printStats()의 구현을 중복되지 않도록 모든 유지 mixin에 걸쳐 실행하는 대상 함수의 이름을 받아 일반 (템플릿) 함수를 만들 든 가능한 경우

이 궁금해 나는 BaseSensor::update()BaseSensor::printStats()에서 다음을 부를 것이다 어떻게하는 방법 runAll()

template<typename ... SensorType> 
class BaseSensor : public SensorType ... //to my BaseSensor class 
{ 
    void update() /*{ what goes in here??? }*/ 
    void printStats() /*{ what goes in here??? }*/ 

    template<typename FnName> 
    void runAll(FnName f) 
    { 
     int arr[] = { (SensorType::f(), 0)..., 0 }; 
     (void)arr; 
    } 
}; 

를 만들 수 있습니다. (그것을 기대하지 않았다) 나는

void update() { runAll<update>(); } 
void printStats() { runAll<printStats>(); } 

를 사용하려고했지만이 작동하지 않습니다. 내가 볼 함수 인수 (로 함수 이름을 전달하는 문제는 here 내가 BaseSensor::update()에서 다양한 ::update() 기능을 가리 키도록 방법을 모르는 것입니다 같은 다른 많은 질문입니다. 예를 들어

void update() { runAll<update>(update()); } 

도 정확하지 않습니다

이 경우 복사를 피할 수 있습니까? C++ 11을 사용하여 복사를 많이하지 않도록 (예 : here과 같이 일반 람다를 사용하지 않고) 한 줄로 수행 할 수 있습니까? 템플리트 매개 변수는 마치 "sensor.t.hpp"파일로 작업 할 곳을 runAll()으로 이동하는 것처럼 보입니까?

고맙습니다.

+4

링크 전용 답변이 나쁘고 질문에 대해서도 동일하게 적용됩니다. 자급 자족 할 수 있도록 관련 부분을 추가하십시오. – Jarod42

+1

@ Jarod42 ok ok – nass

답변

2

됩니다를 구조를 만들고 오버로드에 의존하여이를 해결합니다. 두 개 이상의 함수가 호출해야하는 경우

#include<iostream> 

struct Executor { 
    template<typename T> 
    static void execute(int, T &t) { 
     t.update(); 
    } 

    template<typename T> 
    static void execute(char, T &t) { 
     t.printStats(); 
    } 
}; 

struct EdgeSensor 
{ 
    void update() { std::cout << "EdgeSensor::update" << std::endl; } 
    void printStats() { std::cout << "EdgeSensor::printStats" << std::endl; } 
}; 

struct TrendSensor 
{ 
    void update() { std::cout << "TrendSensor::update" << std::endl; } 
    void printStats() { std::cout << "TrendSensor::printStats" << std::endl; } 
}; 

template<typename ... SensorType> 
class BaseSensor : public SensorType ... 
{ 
    template<typename T> 
    void execute() { 
     int arr[] = { (Executor::execute(T{}, static_cast<SensorType&>(*this)), 0)..., 0 }; 
     (void)arr; 
    } 

public: 
    void update() { 
     execute<int>(); 
    } 

    void printStats() { 
     execute<char>(); 
    } 
}; 

int main() { 
    BaseSensor<EdgeSensor,TrendSensor> ets; 
    ets.update(); 
    ets.printStats(); 
} 

, 내가 choice 트릭은 여기에 잘 적용 같아요
그것은 최소한의 근로 예를 들어 다음과 같습니다.

+0

hm 여전히 구조체에있는 다른 모든 유사한 함수에 대해 복제해야하는 부분이 있습니다. 그것은 진정한 유일한 방법은 일반적인 lambdas가 나타납니다 ... – nass

+2

정보가 아닌'char' /'int' 대신 디스패치 용으로 열거 형/태그를 사용할 것입니다 – Jarod42

+0

@ Jarod42 저도 그렇게 할 것입니다. 필자가 생각하기에,'int' /'char' 트릭은 예를 들어보다 간결합니다. – skypjack

1

당신은 수동으로 일반적인 람다 제 (의 단순화 된 버전)를 작성할 수 있습니다

void update() { 
    execute([](auto &t) { t.update(); }); 
} 

만큼 기능이 두, 당신은 전용을 사용할 수 있습니다 호출 할 수 있도록

void update() { 
    struct { 
     template <typename T> 
     void operator() (T& t) const { t.update(); } 
    } updater; 
    execute(updater); 
} 
+0

안녕하세요, 정보를 제공해 주셔서 감사합니다. 이것은 여전히 ​​복사 - 붙여 넣기를위한 "긴"것처럼 보인다. 이상적으로, 구조체를 어떻게 든 "꺼내"얻을 수 있고't.update()'함수 호출에 "변수"이름을 제공 할 수 있습니까? 고맙습니다. – nass

+0

실제로 _second_ 함수를 도입 할 때는 매우 까다 롭습니다. – skypjack

관련 문제