По какой-то причине @ Макс ответ не является нулевой стоимостью (генерирует инструкции test
и je
).Ниже моя версия с ++ 14 с нулевой стоимостью.https://gcc.godbolt.org/z/kwgMZK
#include <type_traits>
//User Objects
template<class Obj>
struct Msg1;
template<class Obj>
struct Msg2;
template<class Obj>
struct Msg3;
struct Obj1;
struct Obj2;
struct Obj3;
struct Obj4;
template<class MsgType, class ObjType>
void TestFunction(void);
namespace helper {
template<template<class Obj> class Msg>
struct TMsg {
template<class O>
using RMsg = Msg<O>;
};
template<class... Type>
struct Wrap{};
template<class Msg>
void caller1(Msg, Wrap<>){}
template<class Msg, class Obj, class... Objs>
void caller1(Msg m, Wrap<Obj, Objs...> O) {
Obj o;
using TMsgL = typename std::remove_reference<decltype(*m)>::type;
using ObjL = typename std::remove_reference<decltype(*o)>::type;
using MsgL = typename TMsgL::template RMsg<ObjL>;
TestFunction<MsgL, ObjL>();
Wrap<Objs...> r;
caller1(m, r);
}
template<class... Objs>
void caller(Wrap<>, Wrap<Objs...>){}
template<class Msg, class... Msgs, class... Objs>
void caller(Wrap<Msg, Msgs...> M, Wrap<Objs...> O){
Msg m;
caller1(m, O);
Wrap<Msgs...> ML;
caller(ML, O);
}
}
void foo(){
using Msgs = helper::Wrap<helper::TMsg<Msg1>*, helper::TMsg<Msg2>*, helper::TMsg<Msg3>*>;
using Objs = helper::Wrap<Obj1*, Obj2*, Obj3*, Obj4*>;
Msgs m;
Objs o;
caller(m, o);
}
Генерируемая сборка
foo():
sub rsp, 8
call void TestFunction<Msg1<Obj1>, Obj1>()
call void TestFunction<Msg1<Obj2>, Obj2>()
call void TestFunction<Msg1<Obj3>, Obj3>()
call void TestFunction<Msg1<Obj4>, Obj4>()
call void TestFunction<Msg2<Obj1>, Obj1>()
call void TestFunction<Msg2<Obj2>, Obj2>()
call void TestFunction<Msg2<Obj3>, Obj3>()
call void TestFunction<Msg2<Obj4>, Obj4>()
call void TestFunction<Msg3<Obj1>, Obj1>()
call void TestFunction<Msg3<Obj2>, Obj2>()
call void TestFunction<Msg3<Obj3>, Obj3>()
add rsp, 8
jmp void TestFunction<Msg3<Obj4>, Obj4>()