I was trying to find the absolute sum of an array.
#include <iostream>
#include <vector>
using namespace std;
int getAbsSum(vector<int> arr) {
int result = 0;
for (int i = 0; i < arr.size(); i++)
{
result += abs(arr[i]);
}
return result;
}
int main() {
cout << getAbsSum([3, 2, -3, -4]);
return 0;
}
but I got this error that says "Expected an identifier" in my main function. I tried adding a typename before the array, like this
cout << getAbsSum(int [3, 2, -3, -4]);
but it did not work.
The meaning of [ ] is not what you convey in your example. [ ] is used to indicate array indices, and it only supports one argument. Hence, the expression 3, 2, -3, -4 in this context means evaluate 3, then evaluate 2, then -3, then -4 and return the result of evaluating -4. See
https://en.cppreference.com/w/cpp/language/operator_other
Because the expressions 3, 2 and -3 have no side effects, the result here is the same as if you just wrote -4.
With respect to expecting an identifier error, the operator [ ] requires a variable in front of it, so arr[1] means return the second object in array (or container) arr.
The solution is to use the correct syntax for list-initialization, which is a form of uniform initialization (do not confuse with aggregate initialization, which is for aggregates. Vectors are not aggregates):
cout << getAbsSum({3, 2, -3, -4});
Also, I recommend not using using namespace std; in the global workspace, but only inside scopes, i.e. in functions, where the effect is limited in scope.
A modern version of this function can be rewritten as follows:
#include <iostream>
#include <vector>
#include <chrono>
template <typename E = int,
template <typename> typename T = std::vector>
E getAbsSum(T<E> const& arr){
E result {};
for (E element : arr)
{
result += abs(element);
}
return result;
}
int main() {
using namespace std;
using namespace std::literals;
cout << getAbsSum({3, 2, -3, -4}) << '\n';
cout << getAbsSum(vector<double>{2.3, 4.5, 6}) << '\n';
cout << getAbsSum(vector<chrono::seconds>{10s, 1min}).count() << '\n';
return 0;
}
This version supports any arithmetic type and any container.
In response to @foodiecookies:
(1) Here, the line E result {}; means that the default constructor for E is called. If we used E result = 0 then there would be an error on initialization of chrono::seconds, but if we used E result, the arithmetic types would not get initialized, which is undefined behavior. E result {} calls the default constructor on complex types and a value of 0 or equivalent (0.f, 0., false, ...) for basic types.
(2) for (auto var : container) is a range-based loop. See
https://en.cppreference.com/w/cpp/language/range-for
It is considered safer and easier to read. Use the old for(;;) when you are not iterating over all the elements in the container.
(bonus) abs(element) finds the correct version of the abs function thanks to Argument Dependent Lookup
https://en.cppreference.com/w/cpp/language/adl
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With