强制通过推导引用模板类型 [英] forcing template type to be reference by deduction

查看:64
本文介绍了强制通过推导引用模板类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个函数 func

template<typename T>
auto func(T arg){
    std::cout << std::boolalpha;
    std::cout << "T is ref: " << std::is_reference<T>::value << '\n';
}

有没有一种方法可以强制 T

Is there a way I can force T to be deduced as a reference type without explicitly specifying the template parameters?

就像能够写类似这样的东西:

Like being able to write something like:

auto main() -> int{
    auto x = 5;
    func(std::ref(x));
}

但不必专门研究 std :: reference_wrapper

static_cast ing并不能阻止的衰减int& 转换为 int T

static_casting does not stop the decay of int& into int for T.

想象我不能更改函数签名。

推荐答案


想象一下我不能更改函数签名。

Imagine that I can not change the function signature.

签名

template<typename T>
auto func(T arg) { ... }

永远不会推论出是引用,因为类型推导适用于参数的表达式类型,并且来自[expr]:

will never deduce a reference because type deduction works on the type of the expression of the arguments, and from [expr]:


表达式最初的类型为对 T 的引用(8.3.2,8.5.3),该类型被调整为 T
之前进行任何进一步的分析。

If an expression initially has the type "reference to T" (8.3.2, 8.5.3), the type is adjusted to T prior to any further analysis.

也就是说,仅在未明确提供模板参数的情况下才进行模板推导。因此,您可以明确指定 T

That said, template deduction only happens if the template parameters are not explicitly provided. So you can explicitly specify T:

auto main() -> int{
    auto x = 5;
    func<int&>(x); // T = int&
}

否则,您可以在两者之间添加一个中间步骤:

Otherwise, you could add a middle step in between:

template <typename T>
auto func_helper(T&& arg) {
    return func<T>(std::forward<T>(arg));
               ↑↑↑
}

因为,在[temp.deduct.call ]:

Because, in [temp.deduct.call]:


如果P是转发引用,且参数是
左值,则类型对A的左值引用为

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将被推导为参考。在您的示例中:

So if func_helper is called with an lvalue, the template parameter P will be deduced as a reference. In your example:

func_helper(x);

T 将被推导出为 int& ,因此我们显式调用了与之前相同的函数: func< int&>

T will be deduced as int&, so we explicitly call the same function as we did before: func<int&>.

func_helper(5);

T 将被推导出为 int ,我们将调用 func< int> ,与调用时的情况相同func 直接。

T would be deduced as int, and we would call func<int>, the same as would have happened if we had called func directly.

这篇关于强制通过推导引用模板类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆