Moha the almighty camel
Moha the almighty camel

Reputation: 4463

template function sum for numeric types and strings

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

Answers (1)

Bo Persson
Bo Persson

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 least traits::length(s) + 1 elements of charT.

Effects: Constructs an object of class basic_string and determines its initial string value from the array of charT of length traits::length(s) whose first element is designated by s, 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

Related Questions