What is the most effective combination of overloads?

I have a function like this:

void init_str(std::string _s)
{
    std::string s{_s};
}

      

And I want to optimize by allowing overloading const char*

to avoid creating a temp std::string

.

void init_str(const char* c)
{
    std::string s{c};
}

      

But I can also use a redirect.

template<typename T>
void init_str(T&& t)
{
    std::string s{std::forward<T>(t)};
}

      

But the preference for overloading by the compiler is as follows:

  • const char*

  • forwarding
  • std::string

So which combination of overloads should I prefer?

+3


source to share


2 answers


Assuming C ++ 11 or better, the most efficient solution is one you haven't tried yet:

void init_str(std::string s)
{
  // just use s
}

      

Since copying will ensure that no unnecessary temporary object is created at all.

this will construct s using the std :: string (const char *) constructor (1 general construct):

init_str("xxx");

      

this creates s using the copy constructor:



std::string x; // 1 constructor
init_str(x);   // 1 copy constructor

      

this creates s with a move constructor

std::string x;            // 1 constuctor
init_str(std::move(x));   // 1 move constructor

      

this doesn't actually create a temporary at all:

std::string get_str() {
    std::string s("xxx");   // 1 constructor, but...
    return s;               // ...because of RVO it constructed at the call site
}

init_str(get_str());        // ... which is actually the constructor of s in init_str arg list
// ... total constructors: 1

      

+7


source


First of all, consider your input parameter:

void init_str(std::string s)
{
    // use s here ...
}

      

Regardless of what you call a function, constructors std::string

should do the most efficient thing possible.

If you call with a temporary it will be moved ( std::move()

). If you call it with const char*

, it will be effectively copied through the overloaded constructor std::string()

.

Thus, you cannot effectively improve the efficiency of parameter string generation.



Your question is not clear whether you want two lines or one. If you need two lines in your function then:

void init_str(std::string s1)
{
    std::string s2 = s1;

    // use s1 & s2 here ...
}

      

Given that you want a copy of the parameter string, moving is not an option. You can't get better than just making the second line equal to the first. The assignment operator std::string

has all the information it needs to create the most efficient copy.

I don't see how this can improve any of your other solutions.

0


source







All Articles