how should I call all functions in a variadic parameter pack if the function return type is void?

白昼怎懂夜的黑 提交于 2019-12-10 21:02:07

问题


I have a parameter pack full of default constructable and then callable objects (like the ExampleFunctor) and want to call all of them in order (left to right). If the return type is anything besides void I can use an initializer list to do this:

struct ExampleFunctor{
    void operator()(){someGlobal = 4;}
};

template<typename... Ts>
struct CallThem {
    void operator()(){
        auto list = {Ts()()...};
    }
}

however if the return type is void this trick does not work.

I could wrap all the Ts in a wrapper returning an int but that seems overkill and this code will be ultimately running on a cortex M3 with 32K of flash so the extra function call overhead of the wrapper is a pain if I compile the unit in debug mode (and debugging in release mode makes my brain hurt).

Is there a better way?


回答1:


With the comma operator:

int someGlobal;

struct ExampleFunctor{
    void operator()(){someGlobal = 4;}
};

template<typename... Ts>
struct CallThem {
    void operator()(){
        int list[] = {(Ts()(),0)...};
        (void)list;
    }
};

int main()
{
    CallThem<ExampleFunctor, ExampleFunctor>{}();
}

Btw I'm not using an initializer_list here but just an array; try yourself which one / if any of them can be thrown away by the compiler. The (void)list is to suppress a warning (unused variable).




回答2:


The compiler should be able to optimize away the function calls here:

template <typename H, typename... Tail>
void call(H head, Tail... tail) {
   head();
   call(tail...);
}
template <typename T>
void call(T fn) {
   fn();
}
template <typename... Args>
void callThem() {
   call(Args()...);
}

But this is untested. Check the generated assembly for your platform.




回答3:


You may use something like:

template<typename... Ts>
struct CallThem;

template<>
struct CallThem<> { void operator()() const {} };

template<typename Tail, typename... Queue>
struct CallThem<Tail, Queue...>
{
    void operator()() const {
        Tail()();
        CallThem<Queue...>()();
    }
};


来源:https://stackoverflow.com/questions/19860851/how-should-i-call-all-functions-in-a-variadic-parameter-pack-if-the-function-ret

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!