Код (Text): #include <iostream> template <class T> void foo(T t) { std::cout << typeid(t).name() << std::endl; } int main() { int array[3] = {0}; std::cout << typeid(array).name() << std::endl; foo(array); return 0; } Хочу внутри foo знать тип элементов массива и его размер! С типом проблем нет, а вот размер не поддается дрессировке! Что делать?! [EDIT] Код (Text): #include <iostream> typedef int int_array[10]; template <class T> struct deduce { }; template <class T, int n> struct deduce<T[n]> { enum { size = n }; }; int main() { int_array arr = {0}; std::cout << typeid(int_array).name() << std::endl; int f = deduce<int_array>::size; return 0; } Так дедьюсица, но этот способ не идет -> придется заставлять юзера делать typedef Хотелось бы без требований и максимально компактно(
IceStudent Потому что дедьюсить значения (в примере - arr) умеют только функции. Классы и структуры умеют дедьюсить только типы (в примере - int_array). [EDIT] Не, ну можно конечно попросить его написать deduce<int[10]>, но это черевато тем, что смена размера массива приведет к внесению изменений во все места, где использовалась deduce<int[10]>.
_DEN_ template <class _Tp, int N> void foo(_Tp(& v)[N]) { printf ("%d", N); } VC 6.0 - это не соберет
_DEN_ А почему не так? Код (Text): #include <vector> #include <iostream> template <class T> foo (std::vector<T> v) { std::cout<<typeid(T).name()<<" "<<v.size(); } main () { std::vector<int> v(10); foo<int>(v); getchar(); }
RedLord Да, я тоже вспомнил, что видел похожий код в strxxx_s, но не нашёл сходу. Кстати, а зачем там такая странная конструкция: (& v)?
IceStudent _Tp& v - вопросов не вызывает _Tp & v [N] - парсер не разгребет. ему нужно подсказать _Tp (&v) [N] - здесь (&v) в скобках, что подсказывает компилятору, что имеем дело со ссылкой
RedLord А вектор не массив? Имхо классы и были введены чтобы решать подобные задачи, например с размером массива. А выкорячиваться пытаясь получить размер встроенного массива, IMHO по определению не верно, так как ну нету во встоенных массива такого. Ясно что такая информация не может быть получена на стадии компиляции. Остаётся только в реалтайме, а это прямая дорога к классам.
Booster нет. это и есть получение информации на стадии компиляции получение размера массива актуальная задача. например, если есть у тебя константная ( с какими-то коэффициентами) таблица как ты ее будешь задавать? как набор push_back в вектор?
RedLord Зачем же push_back. Вообщем по использованию мало чем отличается от обычного массива, а также внутренне. Вектор так же оптимален, как и обычный массив. А преимущества налицо. Так что я вижу только одни плюсы от использования вектора.
Booster это естественно. но и массивы никто не отменял. внутренне они отличаются. Код (Text): void foo() { const int v[]={1,2}; std::vector<int> v1(2); } весь массив разместится в стеке. а в случае с вектором в стеке будут только мемберы вектора. а место для хранения данных будет выделено из динамической памяти.
RedLord А как насчёт аллокатора? Я имел ввиду, что эффективность у них одинакова, а внутренняя реализация конечно отличается. Как-то это не ООП, и вообще очень плохо, ошибиться при передачи параметра очень легко. И конечно это искусственное решение, так как вычисляет это не компилятор.
Booster а откуда он выделяет? есть реализации аллокатора, выделяющего память со стека? с интересом посмотрю. вычисляет как раз компилятор Код (Text): template <class _Tp, int N> int get_sz(_Tp(& v)[N]) { return N; } void test() { int v[]={2,2} int sz = get_sz(v); // sz==2 } явно в функцию размер массива не передается. это и не есть ООП.
RedLord Всё сдаюсь, твоя функция рулит, невнимательно посмотрел. В принципе её можно выдавать из пула, но это гемор конечно.
RedLord +10, супербизон-кросавчег!!! Получается, "как таковой" массив передать нельзя? Либо ссылкой, либо указателем на первый элемент? 2 Беспосчадный даосс. Новое название темы - незачот. Смысл не в выводе массива, а в том, как выполнить декомпозицию типа на шаблонах.