1

Reading about variadic functions, I found a sum function which accepts any number of any numeric type and calculate sum of them.

Having templated nature of this function, I expected it accepts string objects since operator + is defined for strings.

#include <iostream>
#include <string>
#include <type_traits>
#include <utility>

using namespace std;

template <typename T> T sum(T && x)
{
    return std::forward<T>(x);
}

template <typename T, typename ...Args>
typename std::common_type<T, Args...>::type sum(T && x, Args &&... args)
{
    return std::forward<T>(x) + sum(std::forward<Args>(args)...);
}

int main()
{
    auto y = sum(1, 2, 4.5); // OK
    cout << y << endl;

    auto x = sum("Hello!", "World"); // Makes error
    cout << x << endl;

    return 0;
}

Error:

invalid operands of types 'const char [7]' and 'const char [6]' to binary 'operator+'

I expected it concatenates Hello! and World and prints out Hello!World. What is the problem?

1
  • 4
    const char* doesn't have overloaded operator+, like it says in the error. Pretty clear if you ask me. Commented Feb 24, 2013 at 21:17

2 Answers 2

2

String literals are not std::string objects. No operator + is defined for arrays of characters.

As your compiler is telling you, "Hello!" has type const char[7], while "World" has type const char[6]. Try declaring two variables of those types and taking their sum:

int main()
{
    char const a[7] = "Hello!";
    char const b[6] = "World";
    (a + b);
}

And the compiler will show you a similar error:

error: invalid operands of types 'const char [7]' and 
       'const char [6]' to binary 'operator+'

To make your code work, wrap at least one of the two string literals into an std::string object (two corresponding overloads of operator + exist for std::string objects):

auto x = sum(std::string("Hello!") + "World");

or:

auto x = sum("Hello!" + std::string("World"));

Of course, you can also wrap both arguments, but that's unnecessary.

Sign up to request clarification or add additional context in comments.

3 Comments

auto x = sum(string("Hello!"), string("World")); !
@MM.: Yes. That's because you wrap the literals in string objects
It's better I go sleep before asking worse questions!
2

The underlying problem isn't with variadic templates, but with your expectations - string literals, like "hello" are not of type std::string. They're of type char const[N] where N is the number of characters + 1. If you actually construct a string from them (or even just from the first one), it works as expected:

// snip

int main()
{
    auto y = sum(1, 2, 4.5); // OK
    cout << y << endl;

    auto x = sum(std::string("Hello!"), "World"); // OK
    cout << x << endl;

    return 0;
}

Live example.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.