Reputation: 4463
I am playing around with templates. I have the following templates to sum the elements of a vector:
#include<vector>
#include <iostream>
template <class summable>
summable sum (const std::vector<summable> data, summable initial_value = 0){
std::cout<<"in the function"<<std::endl;
for (auto i : data){
initial_value += i;
}
return initial_value;
}
and it is working perfectly fine for numeric types. but If I try to pass a vector of strings, I don't get any compilation errors but the function is not being called.
here is my function main
:
int main(int argc, char** argv) {
vector<string> s {"Hello" , " ", "There" };
cout<<"Before calling the function\n";
cout<<sum(s);
return 0;
}
I just get
Before calling the function
as an output.
if I change the function call to cout<<sum(s, string(" "));
the function works as expected. I am guessing it has to do with the way I am defining the default parameter since 0
is not a valid value for a string (I think).
My question is why am I not getting any errors ? since it was able to compile it should run , no ?
Upvotes: 2
Views: 701
Reputation: 92321
You are on the right track. For std::string
the value 0
is the same as nullptr
, and matches a constructor taking const char*
.
However, it is undefined behavior to pass a null pointer to that constructor. Undefined behavior means that anything can happen.
The standard says:
basic_string(const charT* s, const Allocator& a = Allocator());
Requires:
s
points to an array of at leasttraits::length(s) + 1
elements ofcharT
.Effects: Constructs an object of class
basic_string
and determines its initial string value from the array ofcharT
of lengthtraits::length(s)
whose first element is designated bys
, as indicated in Table 67.
So, if s
is null (or 0
), it doesn't point to an array of charT
, and the preconditions are violated.
And, by the way, you could use summable{}
as a default value for the parameter. That works for any default constructible type.
Upvotes: 5