Reputation: 2821
I'm a C++ newbie. I want to determine the size of string array in C++. Following advice on this forum, I've created a template to give me the size of the array. The releavant code is
virtual std::string _verify_list_or_string(std::string obj[]) {
std::cout << "debug " << sizeof_array(std::string, sizeof(obj)) << std::endl;
The template I'm using is
template <typename T, std::size_t N>
std::size_t sizeof_array( T (&)[N] ) {
return N;
}
I get a compile error: "error: expected primary-expression before ‘,’"
What am I doing wrong?
Upvotes: 0
Views: 1897
Reputation: 254751
The problem is that, despite the []
, the function argument is a pointer and not an array. You can only pass an array to a function by reference, and then it must be a reference to a specific size of array - the size is part of the array's type.
If you need the size of an array that's been passed as a pointer, then some options are:
sizeof_array
, so that the array is passed by reference and the size available as a template parameter;std::array
or std::vector
with an interface that can give you the size.The error is because you're passing nonsense to sizeof_array
. If obj
were an array, then you'd do sizeof_array(obj)
, and the template arguments would be inferred from the type of obj
. But it isn't an array, so that won't work either.
Upvotes: 3
Reputation: 33701
Your function takes one parameter:
std::size_t sizeof_array( T (&)[N] )
// ^^^^^^^^^^
But you're passing two. Moreover, one of them - type:
sizeof_array(std::string, sizeof(obj))
// ^^^^^^^^^^^^ ^^^^^^^^^^^
You'd probably want to pass an obj
variable. But the problem is that obj
is not an array here. So, you can't get size of obj
this way.
Upvotes: 2
Reputation: 283921
That's not how you invoke a template function... arguments, not template parameters go inside the function-call parentheses. That function is designed to infer the template parameters. If inference wasn't possible, you'd call like this:
std::string ary[6];
sizeof_array<std::string, 6>(ary);
Since inference is possible, the compiler will figure out the template parameters if you just pass the argument:
sizeof_array(ary);
Unfortunately for you, that template function only works on arrays, but you have a pointer. There's no size information for you to get to.
Upvotes: 0
Reputation: 154045
The problematic expression is sizeof_array(std::string, sizeof(obj))
: std::string
isn't an expression but a type. Fixing that expression won't help, though: the argument obj
isn't a suitable argument for sizeof_array()
because it has type std::string*
while sizeof_array()
takes an array reference as argument.
Once the array has decayed into a pointer there is no way to recover the array size. If you want to automatically determine the size of an array in a function, you need to pass the array by reference, e.g.:
template <int Size>
std::string _verify_list_or_string(std::string (&obj)[Size]) {
std::cout << "debug " << sizeof_array(obj) << '\n';
return _verify_list_or_string(obj, Size);
}
virtual std::string _verify_list_or_string(std::string* obj, int Size) {
...
}
Note that the primary entry point was turned into a template which can't be virtual
. Thus, it forwards to a virtual
function taking a pointer to the array and its size.
Upvotes: 2