Gauvain
Gauvain

Reputation: 75

string argument in template specialization in C++

In the following code, why the 's' after the string "hello" in the last line is necessary in order to deduce the type of the argument? It is an explicit casting to a string in c++?

#include <iostream>
#include <string>
#include <vector>
using namespace std;

template <class T>
T addition(T const& a, T const& b){ return a + b;}

template <class T, size_t N>
T reduce(T const (&array)[N], T value = {}, T (*p)(T const&,T const&) = addition<T>)
{
  T res = value;
  for (int i = 0; i < N; i++) {
    res = p(res,array[i]);
  }
  return res;
}



double multiply(double const& lhs, double const& rhs)
{
    return lhs * rhs;
}

int main()
{
    double pi[]{0.0505, 0.0505, 0.0405};
    double factorial[]{1.0, 2.0, 3.0, 4.0, 5.0};
    string concat[]{" ", "world"};
    cout << reduce({1,2,3,4,5}) << endl;
    cout << reduce(pi, 3.0) << endl;
    cout << reduce(factorial, 1.0, multiply) << endl;
    cout << reduce(concat, "hello"s) << endl;
}

Upvotes: 4

Views: 85

Answers (2)

Acorn
Acorn

Reputation: 26066

The s in "hello"s is the string literal operator. It returns a std::string, which means the call to reduce will match with the std::string array you are passing as the first argument.

Note that the example would not work if you had not written using namespace std; (which is not really a good idea to write).

Before C++14, you would typically write std::string("hello") instead. Even nowadays, some guidelines prefer to avoid the literals, because you have to first get access to them using using namespace and, as a single character, they may be hard to notice.

Upvotes: 3

Quimby
Quimby

Reputation: 19113

It's no necessary to deduce the argument, but without the s suffix it would not match.

Because decltype("hello") is const char(&)[6] and that would make T=const char*. But that does not match with the first passed argument concat of type std::string(&)[2] which requires T to be std::string.

The s suffix converts string literal to std::string. So yes, it's an explicit cast to a c++ string because in C/C++ string type is not part of the language and instead it's implemented simply as an array.

Upvotes: 1

Related Questions