Следующее из this вопроса, я пытался создать функцию шаблона, которая вызывает все однотипные методы его микшинов. Это было сделано и проверено в предыдущем вопросе.variadic templates с именами функций шаблона и передающими аргументами и возвращаемыми значениями около
Теперь я пытаюсь получить возвращаемое значение SensorType ::
Аналитически:
#include<iostream>
#include <string>
struct EdgeSensor
{
void update(int i) { std::cout << "EdgeSensor::update " << i << std::endl; }
void updat2(const int i) { std::cout << "EdgeSensor::updat2" << i << std::endl; }
std::string printStats() { std::cout << "EdgeSensor::printStats" << std::endl;
return std::string("EdgeSensor::printStats"); }
};
struct TrendSensor
{
void update(int i) { std::cout << "TrendSensor::update" << i << std::endl; }
void updat2(const int i) { std::cout << "TrendSensor::updat2" << i << std::endl; }
std::string printStats() { std::cout << "TrendSensor::printStats" << std::endl;
return std::string("TrendSensor::printStats"); }
};
template <class T, void (T::*)(const int)>
struct Method { };
template<typename ... SensorType>
class BaseSensor : public SensorType ... //to my BaseSensor class
{
template <class T, void(T::*M)(const int)>
int runSingle(Method<T, M> , const int i) {
(this->*M)(i);
return 0;
}
template <class... Ts>
void runAll(const int i) {
int run[sizeof...(Ts)] = { runSingle(Ts{},i)... };
(void)run;
}
public:
void update() {
runAll<Method<SensorType, &SensorType::update>...>(2);
}
void updat2() {
const int k = 3;
runAll<Method<SensorType, &SensorType::updat2>...>(k);
}
void printStats() {
// runAll<Method<SensorType, &SensorType::printStats>...>();
}
};
int main() {
{
BaseSensor<EdgeSensor,TrendSensor> ets;
ets.update();
ets.updat2();
ets.printStats();
}
{
BaseSensor<EdgeSensor> ets;
ets.update();
ets.updat2();
ets.printStats();
}
}
Вышеизложенные компилирует и работает нормально. Проблема в следующем: как я могу собрать возвращаемые значения (std :: strings) из запуска метода mixin SensorType::printStats()
в BaseSensor::printStats()
?
Если я попытаюсь создать вторую версию функций run*
и шаблон Method
, я не могу скомпилировать его. Скажите, что я сделал:
template <class T, void (T::*)()>
struct Method2 { };
template <class T, void(T::*M)()>
int runSingle2(Method2<T, M>) {
(this->*M)();
return 0;
}
template <class... Ts>
void runAll2() {
std::string s;
int run[sizeof...(Ts)] = { s = runSingle2(Ts{})... };
(void)run;
std::cout << "s=" << s << std::endl;
}
public:
void update() {
int k = 4;
runAll<Method<SensorType, &SensorType::update>...>(k);
}
void printStats() {
runAll2<Method2<SensorType, &SensorType::printStats>...>();
}
};
Это не компилируется говоря
g++ -Wall -Wextra -g -std=c++11 -c -o "obj_dbg/main.opp" "main.cpp"
main.cpp: In instantiation of ‘void BaseSensor<SensorType>::printStats() [with SensorType = EdgeSensor, TrendSensor]’:
main.cpp:65:20: required from here
main.cpp:58:8: error: could not convert template argument ‘&EdgeSensor::printStats’ to ‘void (EdgeSensor::*)()’
make: *** [obj_dbg/main.opp] Error 1
Так как я могу захватить возвращаемые значения из SensorType::printStats()
?
Ницца !! Расширение gcc правильно выводит тип массива? –
'auto v = {(this-> SensorType :: update (1), 0) ...};' может быть даже приятнее (позволяет избежать возможной ошибки виртуальной отправки, что невозможно сделать в подходе указателя участника) –
@WF нет, это часть стандарта, однако в этом нет необходимости использовать оператор ',', это расширение GCC означает выражение выражения перед ',', отбрасывать результат, а затем применять выражение после ', ' 'и использовать его значение. Следовательно, у вас есть список инициализаторов с N 0s, – Nim