#c
#c
Вопрос:
Я пытаюсь сконструировать устройство, которое будет делать одно для значения (в частности, собственного типа) и другое для массива примитивов в стиле C.
Это то, что у меня есть сейчас, которое не делает того, что я хочу.
#include <cstdlib>
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
template<class V> void dump_buf(const Vamp; val)
{
cout << "val = " << val << "n";
}
template<class A> void dump_buf(const A ary[])
{
cout << "ary size = " << sizeof(ary) << "n";
for( size_t i = 0; i < sizeof(ary); i )
cout << "t" << i 1 << " : " << ary[i] << "n";
}
int main()
{
cout << "n";
int i = 42;
float f = 3.14f;
unsigned fib[] = {0,1,1,2,3,5};
char s[] = "hello";
dump_buf(i);
dump_buf(f);
dump_buf(s);
dump_buf(fib);
}
Это не работает, потому что ary
имеет тип pointer-to-something, а не array-of-something. Результат для вышеупомянутого (Intel, x64 compile, VS9) является:
val = 42
val = 3.14
ary size = 8
1 : h
2 : e
3 : l
4 : l
5 : o
6 :
7 : ╠
8 : ╠
ary size = 8
1 : 0
2 : 1
3 : 1
4 : 2
5 : 3
6 : 5
7 : 3435973836
8 : 3435973836
Но я хочу, чтобы результат был:
val = 42
val = 3.14
ary size = 6
1 : h
2 : e
3 : l
4 : l
5 : o
6 :
ary size = 6
1 : 0
2 : 1
3 : 1
4 : 2
5 : 3
6 : 5
Обратите внимание, что желаемый результат для строки составляет 6 символов, а не 5 из-за нулевого ограничителя, который является частью массива.
Есть ли какой-либо способ заставить это работать, используя только стандартный C и никаких дополнительных библиотек?
Приемлемым был бы практически любой метод, соответствующий стандарту. Перегрузка, специализация шаблона, переопределение, шаблоны классов… все в порядке. Я широко открыт практически для любой техники, которая позволит достичь моей цели.
Комментарии:
1. Вместо массива в стиле c вы можете использовать std::valarray ( cplusplus.com/reference/std/valarray/valarray ) или std::vector ( cplusplus.com/reference/stl/vector ).
2. @yasouser: Тип входящих данных — массив в стиле C. Это не вариант.
3. @John-Dibling: В этом случае вы можете преобразовать массив либо в std::valarray, либо в std::vector. Если вы хотите использовать vector, то вы делаете:
std::vector<int> v(fib, fib sizeof(myints) / sizeof(int))
. Если вы хотите использовать std::valarray, то:std::valarray<int> arr(fib, sizeof(myints) / sizeof(int))
.4. @yasouser: или вы могли бы написать функцию, которая принимает ссылку на массив, и не выполнять никакого ненужного копирования.
Ответ №1:
Это должно сработать:
template<class A, size_t S> void dump_buf(const A (amp; ary)[S])
{
cout << "ary size = " << S << "n";
for( size_t i = 0; i < S; i )
cout << "t" << i 1 << " : " << ary[i] << "n";
}
Принимая ссылку на массив, а не указатель на начало массива, размер известен и доступен в качестве предполагаемого аргумента шаблона.
Также помните, что это sizeof
указывает размер в байтах, поэтому, когда вам действительно нужно количество объектов в массиве (и вы не можете или не хотите использовать подобный шаблон), вы хотите sizeof(ary)/sizeof(*ary)
. В обоих случаях вам нужен реальный массив, а не указатель на массив, который потерял все знания о размере массива.