Làm thế nào để chuyển một tham chiếu đến một đối số tên kiểu mẫu


16

Có cách nào để chuyển tham chiếu làm đối số cho đối số tên kiểu mẫu không? Tôi có nghĩa là như vậy thay vì truyền một int, ví dụ, để chuyển một tham chiếu đến một 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
}

Tôi biết tôi có thể làm cho thành viên 'ptr' trở thành một tham chiếu đến một con trỏ bằng cách làm cho nó T & trong lớp, nhưng tôi đã tự hỏi liệu điều này có thể được thực hiện từ đối số được truyền cho đối số mẫu không.


Tôi cho rằng bạn muốn ở lại decltype, bởi vì lấy tiêu đề theo nghĩa đen mà bạn có thể viết đơn giảnFoo<int*&>
idclev 463035818

Câu trả lời:


19

Bạn đang tìm kiếm Foo<decltype(a) &> foo1(a).

Một thay thế tối nghĩa hơn (hoạt động trong trường hợp cụ thể này) là Foo<decltype((a))> foo1(a).


1
Ah có ý nghĩa, cảm ơn. Làm thế nào để các dấu ngoặc kép trong dectype ((a)) hoạt động? Làm thế nào mà làm cho nó một tài liệu tham khảo?
Zebrafish

2
@Zebrafish Về cơ bản, decltypehoạt động khác nhau tùy thuộc vào việc bạn đặt cho nó một tên biến hay cái gì khác (một biểu thức tùy ý). decltype(a)trả về loại biến a(vì bạn chỉ cần đặt cho nó một tên biến). decltype((a))mặt khác, cung cấp cho bạn loại biểu thức (a) (cũng là int), với tính năng tham chiếu bổ sung cho biết loại giá trị của biểu thức. [1/2]
HolyBlackCat

(a)(cũng như a) là một giá trị, được biểu thị bằng &(xvalues ​​được đại diện bởi &&, giá trị không thay đổi loại nào cả). Vì các biểu thức không bao giờ có kiểu tham chiếu, nên thực tế decltypecó thể thêm tham chiếu vào kiểu không thể gây ra bất kỳ xung đột nào. [2/2]
HolyBlackCat

3

Thay thế cho câu trả lời trước, bạn có thể sử dụng std :: Reference_wrapper

std :: Reference_wrapper là một mẫu lớp bao bọc một tham chiếu trong một đối tượng có thể sao chép, có thể gán. Nó thường được sử dụng như một cơ chế để lưu trữ các tham chiếu bên trong các thùng chứa tiêu chuẩn (như std :: vector) mà thông thường không thể chứa các tham chiếu.

#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));
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.