Faizuddin Mohammed
Faizuddin Mohammed

Reputation: 4328

Unable to concat strings in C++?

I have a method to log with the following definition:

void log(std::string s) {
    std::string tag = "main";
    std::cout << tag << " :" << s << std::endl;
}

I'm trying to call this method like this:

log("direction" << std::to_string(direction) << ", count: " << std::to_string(count));

direction and count are integers.

I'm getting this following error with << underlined in red:

no operator << matches these operands. operand types are const char [10] << std::string

I have #include<string> in my header to make sure my strings are working as they should.

I tried std::string("direction") and still the issue was same.

Beginner in C++. Help would be appreciated.

Upvotes: 0

Views: 215

Answers (5)

gsamaras
gsamaras

Reputation: 73366

The prototype of your function is void log(std::string s);. It awaits for an std::string. So you need to pass a string to it, not a stream!

So, change this:

log("direction" << std::to_string(direction) << ", count: " << std::to_string(count));

to this:

log("direction" + std::to_string(direction) + ", count: " + std::to_string(count));

where I only changed the << operator to + operator. It will now concatenate everything inside the parentheses to a single std::string.


Your attempt implies that you wanted to pass std::ostream as the parameter. Maybe you want to read C++ Passing ostream as parameter. However, if I were you, I would just overload <<.

Upvotes: 0

Dantes Dantonovich
Dantes Dantonovich

Reputation: 1

why don't you use: // just include thisusing namespace std;

Upvotes: -2

Richard Hodges
Richard Hodges

Reputation: 69882

If you're determined to use the operator<< notation you need an object that understands it.

Here's such an object (I make no claims that this is a good idea):

#include <string>
#include <sstream>
#include <iostream>

void log(std::string s) {
    std::string tag = "main";
    std::cout << tag << " :" << s << std::endl;
}

struct string_accumulator
{
    std::ostringstream ss;

    template<class T>
    friend string_accumulator& operator<<(string_accumulator& sa, T const& value)
    {
        sa.ss << value;
        return sa;
    }

    template<class T>
    friend string_accumulator& operator<<(string_accumulator&& sa, T const& value)
    {
        return operator<<(sa, value);
    }

    operator std::string () { return ss.str(); }
};

inline auto collect() -> string_accumulator
{
    return string_accumulator();
}

int main()
{
    int direction = 1;
    int count = 1;
    log(collect() << "direction" << std::to_string(direction) << ", count: " << std::to_string(count));
}

Upvotes: 0

Ron
Ron

Reputation: 15501

Substitute the << with the + operator as you are manipulating the string, not the stream:

log("direction" + std::to_string(direction) + ", count: " + std::to_string(count));

Upvotes: 2

Vittorio Romeo
Vittorio Romeo

Reputation: 93274

operator<< isn't used for arbitrary string concatenation - it is called an "output stream operator", and it is only used in the context of std::ostream.

When you say...

std::cout << tag << " :" << s << std::endl;

...you're actually writing code roughly equivalent to:

std::cout.operator<<(tag).operator<<(" :").operator<<(s).operator<<(std::endl);

As you can see operator<< knows how to work with std::cout and std::string, but not between strings.


In order to concatenate std::string instances, you can simply use operator+:

log("direction" + std::to_string(direction) + ", count: " + std::to_string(count));

Please note that this concatenation technique is not the most efficient: you might want to look into std::stringstream or simply use std::string::reserve to avoid unnecessary memory allocations.

Upvotes: 2

Related Questions