I would like to write a variadic template function that accepts rvalues and lvalue references. It would capitalize std::strings, and display each parameter after they are capitalized. All lvalues should remain capitalized after the function has ended (i.e. have lvalues passed by reference).
For example, I would like this behaviour:
std::string hello = "hello";
std::string planet = "planet";
std::string earth = "earth";
//the order and amount of rvalues and lvalue references, should not matter
Capitalize_And_Output("hello","planet","earth"); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output(hello,"planet","earth"); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output("hello",planet,"earth"); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output("hello","planet",earth); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output(hello,planet,"earth"); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output(hello,"planet",earth); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output("hello",planet,earth); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output(hello,planet,earth); //outputs: "HELLO PLANET EARTH"
//lvalue references remain changed after the function call
std::cout << hello << std::endl; //outputs: "HELLO"
std::cout << planet << std::endl; //outputs: "PLANET"
std::cout << earth << std::endl; //outputs: "WORLD"
How can I get this above chunk of code to compile and work as shown?
So far, I am able to output the information, but I do not know how to handle the capitalization of the two different value types. The following code will compile, because I have commented out the lines that do not work.
#include <string>
#include <iostream>
#include <algorithm>
template<typename T>
void Capitalize_And_Output(T & str) {
//std::transform(str.begin(), str.end(), str.begin(), ::toupper); <- will not compile
std::cout << str<< std::endl;
return;
}
template<typename First, typename ... Strings>
void Capitalize_And_Output(First & str, const Strings&... rest) {
//std::transform(str.begin(), str.end(), str.begin(), ::toupper); <- will not compile
std::cout << str << " ";
Capitalize_And_Output(rest...);
return;
}
int main() {
std::string hello = "hello";
std::string planet = "planet";
std::string earth = "earth";
//the order and amount of rvalues and lvalue references, should not matter
Capitalize_And_Output("hello","planet","earth"); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output(hello,"planet","earth"); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output("hello",planet,"earth"); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output("hello","planet",earth); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output(hello,planet,"earth"); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output(hello,"planet",earth); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output("hello",planet,earth); //outputs: "HELLO PLANET EARTH"
Capitalize_And_Output(hello,planet,earth); //outputs: "HELLO PLANET EARTH"
//lvalue references keep changed value after the function call
std::cout << hello << std::endl; //outputs: "HELLO"
std::cout << planet << std::endl; //outputs: "PLANET"
std::cout << earth << std::endl; //outputs: "WORLD"
return 0;
}
How can I get this to work?
Maybe the transform function doesn't work, because the rvalues are actually a different type? They are char*s?
What is going through my head:
Do I have to do something with type traits?
Something with R value references?
Something with universal reverences(not really sure what that is though)?
Please correct any misuse of the terminology!