В шаблонной функции C ++ я могу вернуть разыменованный тип аргумента? - PullRequest
5 голосов
/ 17 января 2010

Я имею в виду следующее. Я хочу шаблонную функцию, которая берет два векторных итератора (или два указателя на массив double) и возвращает double, который каким-то образом связан с векторными итераторами или указателями массива, которые я передаю. Однако я хочу, чтобы это работало для типа double, int или любого арифметического типа.

Я думаю, что мне нельзя говорить:

template <class T> 
T* func(T Begin, T End)

 T new_variable = Begin + 5;

 return (*new_variable);
}

потому что компилятор не поймет, что означает T *. Решение, о котором я подумал, состоит в том, чтобы взять то, что я пытаюсь вернуть, и сделать это третьим аргументом:

template <class T> 
void func(T Begin, T End, T* new_variable)

 new_variable = Begin + 5;

 return (*new_variable);
}

Будет ли это работать? Даже если так, есть ли другой способ сделать то, что я пытаюсь сделать? (Извините, если я не был достаточно ясен.)

Ответы [ 2 ]

10 голосов
/ 17 января 2010

Если вы хотите вернуть значение типа double (то есть тип, который вы получите при разыменовании), вы можете использовать черты итератора:

template<typename RandomAccessIterator>
typename std::iterator_traits<RandomAccessIterator>::value_type 
func(RandomAccessIterator a, RandomAccessIterator b) {
    typedef typename std::iterator_traits<RandomAccessIterator>::value_type 
      value_type;

    // use value_type now, when you want to save some temporary
    // value into a local variable, for instance
    value_type t = value_type();
    for(; a != b; ++a) t += *a;
    return t;
}

Они работают для всех итераторов, включая указатели:

int main() {
  int d[3] = { 1, 2, 3 };
  assert(func(d, d + 3) == 6);
}
3 голосов
/ 17 января 2010

Что ж, ваш код противоречит тому, что вы описали в тексте. Если T является типом итератора, то результат итератора разыменования (как вы сказали в тексте) будет не иметь тип T * (как вы, кажется, верите в код). T * - это совершенно противоположная вещь: это то, что вы получите, если взяли адрес вашего итератора, а не разыменовали его.

На самом деле, нет никакого способа выразить «разыменованный тип» с помощью функций языка ядра C ++ (возможно, decltype сделает это в будущем, как в decltype(*T())). Единственный способ описать результат разыменования типа T - это использовать решение на основе библиотеки: черты итератора, как объяснил Йоханнес в своем ответе.

...