假设我有一个函数func
:
template<typename T>
auto func(T arg){
std::cout << std::boolalpha;
std::cout << "T is ref: " << std::is_reference<T>::value << '\n';
}
有没有一种方法可以在不显式指定模板参数的情况下强制将 T
推导为引用类型?
就像能够写出像这样的东西:
auto main() -> int{
auto x = 5;
func(std::ref(x));
}
但不必专门针对 std::reference_wrapper
。
static_cast
ing 不会阻止 int&
衰减为 T
的 int
。
假设我无法更改函数签名。
最佳答案
Imagine that I can not change the function signature.
签名
template<typename T>
auto func(T arg) { ... }
永远不会推导一个引用,因为类型推导适用于参数表达式的类型,并且来自 [expr]:
If an expression initially has the type “reference to
T
” (8.3.2, 8.5.3), the type is adjusted toT
prior to any further analysis.
也就是说,模板推导只有在没有明确提供模板参数的情况下才会发生。所以你可以明确指定 T
:
auto main() -> int{
auto x = 5;
func<int&>(x); // T = int&
}
否则,您可以在两者之间添加一个中间步骤:
template <typename T>
auto func_helper(T&& arg) {
return func<T>(std::forward<T>(arg));
↑↑↑
}
因为,在 [temp.deduct.call] 中:
If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction.
所以如果func_helper
使用左值调用时,模板参数 P 将被推导为引用。在你的例子中:
func_helper(x);
T
将被推断为 int&
,所以我们显式地调用了与之前相同的函数:func<int&>
.
func_helper(5);
T
将被推断为 int
, 我们会调用 func<int>
, 如果我们调用 func
就会发生同样的情况直接地。
关于c++ - 通过推导强制引用模板类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31804946/