Tre*_*key 4 c++ templates overloading function c++17
我想将这两个功能组合到一个功能界面中:
T& Transform(T & foo){
//transform t
return t;
}
T As_Transformed(T foo){
//transform t
return t;
}
Run Code Online (Sandbox Code Playgroud)
有时我想转换传递给函数的变量.
其他时候我想要一个带有应用转换的新变量.
结果,我最终每次都创建了两个函数,并遵循我的一个简单的约定,其中As_take并返回一个副本,而没有As_take并返回一个引用.
如何编写一个能够处理这两种行为的单一函数实现?
我对它应该是什么样子没有任何要求,但我想有一种方法,我不依赖于我的As_约定,理想情况下我只做一个函数而不是两个.
示例:
以下是此示例的示例.
让我们Uppercase()和As_Upercased()
std::string str1 = "hello";
Uppercase(str1); //str is now "HELLO"
std::string str2 = "hello";
auto str3 = As_Uppercased(str2); //str2 is still "hello",
//but str3 is "HELLO"
Run Code Online (Sandbox Code Playgroud)
我不知道组合界面会是什么样子,但也许:
std::string str1 = "hello";
Uppercase<REF>(str1); //str is now "HELLO"
std::string str2 = "hello";
auto str3 = Uppercase<COPY>(str2); //str2 is still "hello",
//but str3 is "HELLO"
Run Code Online (Sandbox Code Playgroud)
或者也许我可以用引用包装器做一些事情.
我正在询问的可能的实现方式.
您可以通过提供重载来告诉编译器如何区分这两者std::reference_wrapper.然后代码看起来像这样,例如:
#include <iostream>
#include <functional>
using T = std::string;
T Transform(T t)
{
t += " copy";
return t;
}
std::reference_wrapper<T> Transform(std::reference_wrapper<T> t)
{
t.get() += " ref";
return t;
}
int main()
{
T t{"original"};
std::cout << Transform(Transform(t)) << "\n";
std::cout << t << "\n";
std::cout << Transform(Transform(std::ref(t))).get() << "\n";
std::cout << t;
}
Run Code Online (Sandbox Code Playgroud)
输出:
original copy copy
original
original ref ref
original ref ref
Run Code Online (Sandbox Code Playgroud)
请注意,原始值在第一个调用链之后如何保持不变,并在第二个调用链之后进行修改.
在您的实际代码中,第一个重载只会调用第二个重载来转换其包装的pass-by-copy参数,std::ref以避免代码重复.