Cof*_*ode 2 c++ templates language-lawyer c++14
假设我有一个功能func:
template<typename T>
auto func(T arg){
std::cout << std::boolalpha;
std::cout << "T is ref: " << std::is_reference<T>::value << '\n';
}
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以强制T将其推导为引用类型,而无需显式指定模板参数?
就像能够写出这样的东西:
auto main() -> int{
auto x = 5;
func(std::ref(x));
}
Run Code Online (Sandbox Code Playgroud)
但不必专门从事std::reference_wrapper.
static_casting 并不能阻止 的衰变int&为intfor T。
想象一下我无法更改函数签名。
\n\n\n想象一下我无法更改函数签名。
\n
签名
\n\ntemplate<typename T>\nauto func(T arg) { ... }\nRun Code Online (Sandbox Code Playgroud)\n\n永远不会推导出引用,因为类型推导适用于参数表达式的类型,并且来自 [expr]:
\n\n\n\n\n如果表达式最初的类型为 \xe2\x80\x9c(对
\nT\xe2\x80\x9d(8.3.2、8.5.3)的引用),则在T任何进一步分析之前将类型调整为\n。
也就是说,只有在未显式提供模板参数的情况下才会发生模板推导。所以你可以明确指定T:
auto main() -> int{\n auto x = 5;\n func<int&>(x); // T = int&\n}\nRun Code Online (Sandbox Code Playgroud)\n\n否则,您可以在两者之间添加一个中间步骤:
\n\ntemplate <typename T>\nauto func_helper(T&& arg) {\n return func<T>(std::forward<T>(arg));\n \xe2\x86\x91\xe2\x86\x91\xe2\x86\x91\n}\nRun Code Online (Sandbox Code Playgroud)\n\n因为,在 [temp.deduct.call] 中:
\n\n\n\n\n如果 P 是转发引用并且参数是左值,则使用对 A\xe2\x80\x9d 的类型 \xe2\x80\x9clvalue 引用代替 A 进行类型推导。
\n
因此,如果func_helper使用左值调用,模板参数 P 将被推导为参考。在你的例子中:
func_helper(x);\nRun Code Online (Sandbox Code Playgroud)\n\nT将被推导为int&,因此我们显式调用与之前相同的函数:func<int&>。
func_helper(5);\nRun Code Online (Sandbox Code Playgroud)\n\nT将被推导为int,并且我们将调用func<int>,与直接调用时发生的情况相同func。