Получить переменные аргументы из аргумента шаблона

У меня есть два шаблона, один передается другому в качестве аргумента. Я хотел бы иметь возможность использовать аргументы из аргумента в основном шаблоне. Или если у меня есть:

template <typename T, typename... Args>
class Foo
{
    typedef T Type;
    static void foo(Args... args)
    {
    }
};

template <typename C>
class Bar
{
    void bar(Args... args)
    {
        // do something
        C::foo(args...);
    }
};

Как я могу сделать Args видимым в шаблоне Bar. Обратите внимание, что с typedef T Type я могу использовать C::Type в Bar. Каков синтаксис, если это возможно для аргумента с переменным числом аргументов?


person gsf    schedule 25.04.2016    source источник
comment
Я видел это. Ответ как-то связан с трюком indecies. stackoverflow.com/a/18993297/845092   -  person Mooing Duck    schedule 25.04.2016
comment
потому что я хочу, чтобы это было   -  person gsf    schedule 25.04.2016
comment
один вариант   -  person Piotr Skotnicki    schedule 25.04.2016


Ответы (2)


Здесь возможное решение на основе параметра шаблона шаблона:

template<typename T>
class Bar;

template <template<typename...> class C, typename... Args>
class Bar<C<Args...>> {
    void bar(Args... args) {
        // do something
        C<Args...>::foo(args...);
    }
};

Вы можете использовать его следующим образом:

Bar<Foo<int, double>> v;

Вы не получаете аргументы Args непосредственно из класса C. Вместо этого идея состоит в том, чтобы использовать тот факт, что класс C является вариативным шаблоном для самого себя, таким образом получая Args из списка параметров специализации шаблона Bar.

person skypjack    schedule 25.04.2016
comment
это не отвечает на вопрос, но это лучший вариант из того, что я пытался сделать - я отмечу это как решение - person gsf; 26.04.2016
comment
@gsf Ну, на самом деле таким образом вы можете использовать Args из аргумента в основном шаблоне. Таким образом, это также действительно отвечает на вопрос. ;-) - person skypjack; 26.04.2016

У вас может быть typedef для «списка типов», который обертывает Args.... Вот пример использования tuple для выполнения роли списка типов:

#include <tuple>
#include <experimental/tuple>

template <typename T, typename... Args>
class Foo
{
public:
    using Type = T;

    using Arguments = std::tuple<Args...>;

    static void foo(Args... args)
    {
    }
};

template <typename C>
class Bar
{
public:
    void bar(typename C::Arguments &&args)
    {
        // do something
        std::experimental::apply(C::foo, args);
    }
};

int main() {
    Bar<Foo<int, double, float>> b;
    b.bar(std::make_tuple(2.0, 1.0f));
}

Приложив немного больше метапрограммирования, можно создать функцию Bar::bar, которая принимает аргументы непосредственно на основе C::Arguments.

person bames53    schedule 25.04.2016