C ++ - typedef «внутри» аргументов шаблона? - PullRequest
4 голосов
/ 29 марта 2010

Представьте, что у меня есть шаблонная функция, подобная этой:

template<typename Iterator>
void myfunc(Iterator a, typename Iterator::value_type b)
{ ... }

Есть ли способ реализовать то же самое, объявив typedef для Iterator :: valuetype, который я могу использовать в сигнатуре функции?Например, я предпочел бы иметь возможность делать что-то вроде этого:

template<
    typename Iterator,
    typedef Iterator::value_type type>
void myfunc(Iterator a, type b)
{ ... }

До сих пор я прибегал к использованию аргументов шаблона по умолчанию и проверке концепции Boost, чтобы гарантировать, что по умолчанию всегда используется:

template<
    typename Iterator,
    typename type = typename Iterator::value_type >
void myfunc(Iterator a, type b)
{
     BOOST_STATIC_ASSERT((
         boost::is_same<
             typename Iterator::value_type, 
             type
         >::value
     ));
     ...
}

... но было бы неплохо, если бы в языке существовала поддержка для такого типа вещей.

Edit

Я, вероятно,должен был использовать класс вместо функции, так как аргументы по умолчанию не являются стандартными для функций.

template<
    typename T,
    typename V = typename T::value_type>
class A : public B<T, V>  
{
    BOOST_STATIC_ASSERT((boost::is_same<typename T::value_Type, V>::type));
};

Ответы [ 2 ]

2 голосов
/ 29 марта 2010

Вы ищете шаблонную typedef, которая будет использоваться внутри определения шаблонной функции. Я не думаю, что вы можете сделать это ...

У вас может быть шаблонный класс со статической функцией & typedefs ... Но его использование становится уродливым:

template<typename Iterator>
class arbitraryname
{
public:
  typedef typename Iterator::value_type  value;

  static void myfunc( Iterator a, value b )
  {
    value c = b;
    cout << "Test" << c << endl;    
  }
};

struct Foo
{
  typedef int value_type;
};

int main()
{
  Foo f;
  myfunc<Foo>(f,2); // Old way.
  arbitraryname<Foo>::myfunc(f,3); // With templated class.
}

Лично в этом случае я бы выбрал # define ...

#define VALUE_TYPE  typename Iterator::value_type
template<typename Iterator>
void myfunc(Iterator a, VALUE_TYPE b)
#undef VALUE_TYPE
{
  typedef typename Iterator::value_type  bar;
  bar z = b;
  cout << "Test" << z << endl;
}

Конечно # определяют уродливые и греховные. Но так же и код, который мучительно тупо читать ...

p.s. На всякий случай, вы можете добавить:

#ifdef  VALUE_TYPE
#error "VALUE_TYPE already defined!"
#endif
2 голосов
/ 29 марта 2010

Вы можете использовать typename в списке параметров:

template <typename Iterator>
void myfunc(Iterator a, typename Iterator::value_type b)
{ 
}
...