如何传递对模板 typename 参数的引用

How to pass a reference to a template typename argument

提问人:Zebrafish 提问时间:3/25/2020 更新时间:3/25/2020 访问量:1868

问:

有没有办法将引用作为参数传递给模板类型名参数?我的意思是,而不是传递一个 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”成员成为指针的引用,但我想知道这是否可以通过传递给模板参数的参数来完成。

C++ 模板

评论

0赞 463035818_is_not_an_ai 3/25/2020
我想你想留下来,因为从字面上看标题你可以简单地写decltypeFoo<int*&>

答:

19赞 HolyBlackCat 3/25/2020 #1

您正在寻找 .Foo<decltype(a) &> foo1(a)

一个更晦涩的替代方法(适用于这种特定情况)是 。Foo<decltype((a))> foo1(a)

评论

1赞 Zebrafish 3/25/2020
啊,这是有道理的,谢谢。decltype((a)) 中的双括号是如何工作的?这如何使它成为参考?
2赞 HolyBlackCat 3/25/2020
@Zebrafish 基本上,decltype 的工作方式不同,具体取决于您是给它一个变量名称还是其他名称(任意表达式)。 返回变量的类型(因为您只是给它指定了一个变量名称)。另一方面,为您提供表达式的类型(也是 ),并添加了指示表达式值类别的引用性。[1/2]decltype(a)adecltype((a))(a)int
0赞 HolyBlackCat 3/25/2020
(a)(以及 ) 是一个左值,由(x值由 表示,pr值根本不改变类型)。由于表达式从未具有引用类型,因此可以向类型添加引用性这一事实不会引起任何冲突。[2/2]a&&&decltype
3赞 Picaud Vincent 3/25/2020 #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));
}