2013-05-12 8 views
7

Я изучаю концепции шаблонов C++. Я не понимаю следующее.Как передать массив в шаблон функции со ссылкой

#include <iostream> 
#include <typeinfo> 

using namespace std; 

template <typename T> 
T fun(T& x) 
{ 
cout <<" X is "<<x; 
cout <<"Type id is "<<typeid(x).name()<<endl; 
} 


int main (int argc, char ** argv) 
{ 
    int a[100]; 
    fun (a); 
} 

Что я пытаюсь?

1) T весело (T & х)

Здесь х является ссылкой, и, следовательно, не распадались «а» в тип указателя, но во время компиляции, я получаю следующее сообщение об ошибке.

error: no matching function for call to ‘fun(int [100])’ 

Когда я пытаюсь использовать ссылку, она отлично работает. Насколько я понимаю, массив распадается на тип указателя.

ответ

16

C-style массивы - это очень простые конструкции, которые нельзя присваивать, копировать или ссылаться так, как это делают встроенные или пользовательские типы. Для достижения эквивалента передачи массива по ссылке, вам необходимо иметь следующий синтаксис:

// non-const version 
template <typename T, size_t N> 
void fun(T (&x)[N]) { ... } 

// const version 
template <typename T, size_t N> 
void fun(const T (&x)[N]) { ... } 

Обратите внимание, что здесь размер массива также является параметр шаблона, чтобы функция для работы будет всех размерами массива, так как T[M] и T[N] не идентичны для разных M, N. Также обратите внимание, что функция возвращает void. Нет способа вернуть массив по значению, так как массив не может быть скопирован, как уже упоминалось.

4

Проблема в обратном типе: вы не можете вернуть массив, потому что массивы не копируются. И, кстати, вы ничего не возвращаете!

Попробуйте вместо этого:

template <typename T> 
void fun(T& x) // <--- note the void 
{ 
    cout <<" X is "<<x; 
    cout <<"Type id is "<<typeid(x).name()<<endl; 
} 

И он будет работать, как ожидалось.

Примечание: оригинальный полное сообщение об ошибке (с GCC 4.8) на самом деле:

test.cpp: In function ‘int main(int, char**)’: 
test.cpp:17:10: error: no matching function for call to ‘fun(int [100])’ 
    fun (a); 
    ^
test.cpp:17:10: note: candidate is: 
test.cpp:7:3: note: template<class T> T fun(T&) 
T fun(T& x) 
^
test.cpp:7:3: note: template argument deduction/substitution failed: 
test.cpp: In substitution of ‘template<class T> T fun(T&) [with T = int [100]]’: 
test.cpp:17:10: required from here 
test.cpp:7:3: error: function returning an array 

Наиболее значимой линией является последним.

+0

Пункт 1 в «эффективном современном C++» также предлагает этот способ. Написание '(& param) [N]' избыточно, если вам не нужно ссылаться на 'N' в теле' f' (хотя это также можно вывести после того, как у вас есть тип) –

Смежные вопросы