Каким образом можно получить значение аргумента константы вариабельного шаблона C ++ в позиции N? - PullRequest
4 голосов
/ 25 января 2011

Я хотел бы знать, как правильно получить значение аргумента константы переменной шаблона в позиции N (N известно во время компиляции).Например, допустим, у вас есть шаблон, который получает в качестве аргументов переменное число указателей на функции, и вам нужно получить второй указатель на функцию.Пока все, что я смог придумать, это ...

typedef int (*func)(int);

template< func... F >
struct testme
{
 inline int getme(int p) const
 {
  return std::array< func , sizeof... (F) >{F...}[1](p);
 }
};

... что, само собой разумеется, очень хакерское.Есть лучший способ сделать это?Спасибо.

РЕДАКТИРОВАТЬ:

Основываясь на коде typedeftemplate, я сделал версию, которая может принимать любой тип в качестве аргумента шаблона переменной.Он был протестирован для работы над экспериментальной сборкой GCC 4.6.Я понял, что это может быть полезно для кого-то еще, так что это ...

template< std::size_t I, typename T, T... Args >
struct va_lookup;

template< std::size_t I, typename T, T Arg, T... Args >
struct va_lookup< I, T, Arg, Args... >
{
    static_assert(I <= sizeof... (Args), "index is out of bound");
    static constexpr T value = va_lookup< I - 1, T, Args... >::value;
};

template< typename T, T Arg, T... Args >
struct va_lookup< 0, T, Arg, Args... >
{
    static constexpr T value = Arg;
};

Ответы [ 2 ]

4 голосов
/ 25 января 2011

Вы можете использовать что-то в этом духе, я думаю:

template <int Index, int... Args> struct LookupAtIndex;
template <int Index, int First, int... Rest> struct LookupAtIndex<Index, First, Rest...> {
    static constexpr int result = LookupAtIndex<Index - 1, Rest...>::result;
};
template <int First, int... Rest> struct LookupAtIndex<0, First, Rest...> {
    static constexpr int result = First;
};

Я не проверял это, но, по крайней мере, интуитивно кажется, что все должно работать правильно.

1 голос
/ 25 января 2011

Вот вариант вашего решения, который может быть более приемлемым:

typedef int (*func)(int);

template< func... F >
struct testme
{
    static const std::array< func , sizeof... (F) > ptrs_;

    int getme(int p) const
    {
        return ptrs_[1](p);
    }
};

template< func... F >
const std::array< func , sizeof... (F) >
testme<F...>::ptrs_ = {F...};

Одна из основных проблем, связанных с вашим вариантом использования, заключается в том, что указатели на функции не так просто выполнить мета-программирование скак целочисленные типы.

...