Muszę wywołać funkcję - template lub przeciążoną - dla każdego elementu w arbitralnej krotce. Mówiąc dokładniej, muszę wywołać tę funkcję na elementach, które są określone w krotce.Stosowanie func do elementów w std :: tuple w naturalnej (nie odwrotnej) kolejności
Na przykład. Mam krotki std::tuple<int, float> t{1, 2.0f};
i funkcjonalny
class Lambda{
public:
template<class T>
void operator()(T arg){ std::cout << arg << "; "; }
};
Potrzebuję struct/funkcję Apply
, które, jeśli nazywa jak Apply<Lambda, int, float>()(Lambda(), t)
będzie wydajność:
1; 2.0f;
i nie 2.0f; 1;
.
Zauważ, że znam rozwiązanie, jeśli pakiet parametrów "raw" jest przekazywany do funkcji i wiem, jak to zrobić dla krotek w odwrotnej kolejności. Ale po próba częściowo specjalizujący Apply
zawiedzie:
template<class Func, size_t index, class ...Components>
class ForwardsApplicator{
public:
void operator()(Func func, const std::tuple<Components...>& t){
func(std::get<index>(t));
ForwardsApplicator<Func, index + 1, Components...>()(func, t);
}
};
template<class Func, class... Components>
class ForwardsApplicator < Func, sizeof...(Components), Components... > {
public:
void operator()(Func func, const std::tuple<Components...>& t){}
};
int main{
ForwardsApplicator<Lambda, 0, int, float>()(Lambda{}, std::make_tuple(1, 2.0f));
}
kod jest kompilowany ale tylko pierwszy argument jest drukowany. Jednakże, jeśli mogę wymienić specjalizację ForwardsApplicator
z
template<class Func, class... Components>
class ForwardsApplicator < Func, 2, Components... >{...}
działa poprawnie - ale oczywiście tylko na krotki o długości 2. Jak to zrobić - jeśli to możliwe, elegancko - dla krotek dowolnej długości?
EDYCJA: Dzięki chłopaki za odpowiedzi! Wszystkie trzy są naprawdę proste i wyjaśniają problem ze wszystkich możliwych punktów widokowych.
Oto odpowiedź, której szukałem: elegancki i bardzo zbliżony do projektu, który miałem na myśli. Dzięki! – Mischa
Masz rację, że ten wyspecjalizowany nie szablonowy argument jest nielegalny. Myślę, że OP używa VC12, który nie wydaje żadnych błędów, ale też nie robi nic dobrego; problem został rozwiązany w CTP5 VC14, który wydaje miły błąd. Warto zauważyć, że Clang (3.5.0, a także trunk 228146) kompiluje kod bez diagnostyki i pasuje również do specjalizacji. Należy to zgłosić. – bogdan