【问题标题】:universal reference in void foo(T<U>&& param)void foo(T<U>&& param) 中的通用引用
【发布时间】:2015-02-19 11:51:48
【问题描述】:

在模板模板参数的情况下,是否可以使void foo 采用通用引用而不是右值引用,如下面的代码所示?

#include <iostream>
#include <string>
using namespace std;

template <int I>
struct s
{
    string str;
};

template <template<int> class T, int U>
void foo(T<U>&& param)
{
    cout << param.str << endl;
}

int main()
{
    s<5> thing;
    foo( thing );
}

我收到following error

error: cannot bind 's<5>' lvalue to 's<5>&&'

【问题讨论】:

  • 没有。转发引用(所谓的“通用引用”的官方名称)必须是T&amp;&amp;,其中T 是正在推导的模板类型参数。

标签: c++ c++11 rvalue-reference forwarding-reference


【解决方案1】:

不,通用引用依赖于被推导出为左值引用的模板参数。 T 不能是 T&lt;U&gt;&amp;&amp; 中的左值引用,所以这不起作用。

可以使用T&amp;&amp;,并使用SFINAE 要求它匹配一些T&lt;U&gt;

template <template<int> class T, int U>
void foo_helper(const volatile T<U>&);

template <template<int> class T, int U>
void foo_helper(const volatile T<U>&&);

template <typename T, typename = decltype(foo_helper(std::declval<T>()))>
void foo(T&& param)
{
  cout << param.str << endl;
}

如果需要,如果 foo 打算直接使用您的 TU,您还可以提供帮助类型特征。

【讨论】:

  • 这个例子展示了如何在 foo 中使用 U:coliru.stacked-crooked.com/a/0cc2f28bf549bfbf
  • @MofX 既然我已经有了foo_helper,我认为使用typename Traits = decltype(foo_helper(std::declval&lt;T&gt;)) 会更容易,并使foo_helper 返回foo_traits&lt;T, U&gt;(其中将包含任何foo需要)。
猜你喜欢
  • 1970-01-01
  • 2014-11-09
  • 2021-02-18
  • 1970-01-01
  • 2020-03-08
  • 2011-02-08
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
相关资源
最近更新 更多