obrecarga da função @rvalue

Eu quero sobrecarregar uma função para que ele manipule seu argumento de alguma maneira e depois retorne uma referência ao argumento - mas se o argumento não for mutável, ele deverá retornar umcópia d do argumento. Depois de mexer com ele por séculos, aqui está o que eu inventei.

using namespace std;

string& foo(string &in)
{
    in.insert(0, "hello ");
    return in;
}

string foo(string &&in)
{
    return move(foo(in));
}

string foo(const string& in)
{
    return foo(string(in));
}

Este código parece funcionar corretamente, mas estou interessado em saber se alguém pode pensar em uma maneira melhor de fazê-l

Aqui está um programa de teste:

int main(void)
{
    string var = "world";
    const string var2 = "const world";
    cout << foo(var) << endl;
    cout << var << endl;

    cout << foo(var2) << endl;
    cout << var2 << endl;

    cout << foo(var + " and " + var2) << endl;
    return 0;
}

A saída correta é

hello world
hello world
hello const world
const world
hello hello world and const world

Eu acho que seria um pouco mais limpo se eu pudesse fazer isso:

string& foo(string &in)
{
    in.insert(0, "hello ");
    return in;
}

string foo(string in)
{
    return move(foo(in));
}

Claro, isso não funciona porque a maioria das chamadas de função parafoo seria ambíguo - incluindo a chamada emfoo em si! Mas se eu pudesse de alguma forma dizer ao compilador para priorizar o primeiro ...

Como eu disse, o código que publiquei funciona corretamente. A principal coisa que eu não gosto é o código extra repetitivo. Se eu tivesse um monte de funções assim, isso se tornaria uma bagunça, e a maior parte seria muito repetitiva. Então, como uma segunda parte da minha pergunta: alguém pode pensar em uma maneira de gerar automaticamente o código para o segundo e o terceirofoo funções? por exempl

// implementation of magic_function_overload_generator
// ???

string& foo(string &in);
magic_function_overload_generator<foo>;

string& bar(string &in);
magic_function_overload_generator<bar>;

// etc

questionAnswers(5)

yourAnswerToTheQuestion