2016-09-18 19 views
-1

thisの質問に続いて、私は、クラスBaseSensorのミックスインの同じ名前のメソッドをすべて呼び出すことに関連するコードをコピーして貼り付けることを避けようとしています。C++のテンプレート関数名を持つ可変テンプレート11

sensor.hpp main.cppにで

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??? }*/ 
}; 
sensor.t.hppで

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; 
} 

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

に上記のコードは、内のすべてのミックスインのupdate()を実行しますすべてのミックスインからprintStats()のすべてを実行する前に、オンにします。例えば

、:BaseSensor::update()BaseSensor::printStats()の実装の重複を避けるため、すべてのミックスイン間で実行するために、ターゲット関数の名前を受け入れるジェネリック(テンプレート)関数を作成するために何とかできるかどう

は、私が疑問に思います私は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"ファイルに移動するかのように見えますか?

ありがとうございます。

+4

リンクのみの回答が悪く、質問にも同じことが適用されます。自立するために関連する部分を追加してください。 – Jarod42

+1

@ Jarod42 ok fixed – 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まだ他のすべての同様の機能のために複製する必要がある部分(構造体内)があります。 – nass

+2

情報がない 'char' /' int'の代わりにディスパッチするためにenum/tagを使用する – Jarod42

+0

@ Jarod42私はそれもやっています。私の視点から見ると、 'int' /' char'トリックは一例でより簡潔です。それだけです。 – skypjack

1

あなたはまだ手動でジェネリックラムダ(のバージョンを簡素化)を書き込むことができます。

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

は限り呼び出される関数は2つですように

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

こんにちは、情報ありがとうございます。これはまだコピー貼り付けのためには「長い」ようです。理想的には、構造体を何らかの形で "出力"し、 't.update()'関数呼び出しのための "変数"名を与えることができますか?ありがとうございます – nass

+0

実際に_second_関数を導入する場合は、これは非常に難しいです。 – skypjack

関連する問題