【问题标题】:How to pass a reference to a template typename argument如何传递对模板类型名参数的引用
【发布时间】:2020-03-25 13:20:22
【问题描述】:

有没有办法将引用作为参数传递给模板类型名参数?我的意思是,而不是传递一个 int,例如,传递一个对 int 的引用。

template <typename T>
struct Foo
{
    Foo(T arg) : ptr(arg) {}
    T ptr;
};

int main() 
{
    int* a = new int(6);
    Foo<decltype(a)> foo1(a); // ptr is a copy of a pointer
    Foo<decltype(&a)> foo1(&a); // ptr seems to be a pointer to a pointer
}

我知道我可以通过在类中将“ptr”成员设置为对指针的引用,但我想知道这是否可以通过传递给模板参数的参数来完成。

【问题讨论】:

  • 我想你想留在decltype,因为从字面上看你可以简单地写Foo&lt;int*&amp;&gt;

标签: c++ templates


【解决方案1】:

您正在寻找Foo&lt;decltype(a) &amp;&gt; foo1(a)

一个更模糊的替代方案(适用于这种特定情况)是Foo&lt;decltype((a))&gt; foo1(a)

【讨论】:

  • 嗯,有道理,谢谢。 decltype((a)) 中的双括号是如何工作的?这如何使它成为参考?
  • @Zebrafish 基本上,decltype 的工作方式不同,具体取决于您是否给它一个变量名或其他名称(任意表达式)。 decltype(a) 返回变量 a 的类型(因为你只是给它一个变量名)。另一方面,decltype((a)) 为您提供 表达式 (a)(也是int)的类型,并添加了指示表达式值类别的引用性。 [1/2]
  • (a)(以及a)是一个左值,用&amp;表示(xvalues用&amp;&amp;表示,prvalues根本不改变类型)。由于表达式从来没有引用类型,decltype 可以向类型添加引用性这一事实不会导致任何冲突。 [2/2]
【解决方案2】:

作为上一个答案的替代方案,您可以使用std::reference_wrapper

std::reference_wrapper 是一个类模板,它将引用包装在 可复制的,可分配的对象。它经常被用作一种机制 将引用存储在标准容器(如 std::vector)中 通常不能保存引用。

#include <functional>

template <typename T>
struct Foo
{
  Foo(T arg) : ptr(arg)
  {
  }
  T ptr;
};

int main()
{
  int* a = new int(6);

  Foo<std::reference_wrapper<int*>> foo1(std::ref(a));
  foo1.ptr[0] = 1;  // ok

  // This also works
  int* b = new int(6);
  Foo<std::reference_wrapper<decltype(b)>> foo2(std::ref(b));
  // and this too
  foo1 = foo2;

  // Or, if you use c++17, even this
  Foo foo3(std::ref(b));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    相关资源
    最近更新 更多