วิธีส่งการอ้างอิงไปยังอาร์กิวเมนต์ชื่อเทมเพลต


16

มีวิธีส่งการอ้างอิงเป็นอาร์กิวเมนต์ไปยังอาร์กิวเมนต์พิมพ์ชื่อแม่แบบหรือไม่ ฉันหมายถึงเช่นนั้นแทนที่จะผ่าน 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' เป็นตัวอ้างอิงถึงตัวชี้โดยทำให้ T & อยู่ในชั้นเรียน แต่ฉันสงสัยว่าสิ่งนี้สามารถทำได้จากการโต้แย้งที่ส่งผ่านไปยังอาร์กิวเมนต์เทมเพลต


ฉันคิดว่าคุณต้องการที่จะอยู่กับdecltypeเพราะการใช้ชื่ออย่างแท้จริงคุณก็สามารถเขียนFoo<int*&>
idclev 463035818

คำตอบ:


19

Foo<decltype(a) &> foo1(a)คุณกำลังมองหา

ทางเลือกที่ชัดเจนมากขึ้น (ซึ่งทำงานในกรณีนี้โดยเฉพาะ) Foo<decltype((a))> foo1(a)เป็น


1
อานั่นทำให้รู้สึกขอบคุณ เครื่องหมายวงเล็บคู่ใน decltype (()) ทำงานอย่างไร สิ่งนี้ทำให้เป็นข้อมูลอ้างอิงได้อย่างไร
Zebrafish

2
@Zebrafish โดยทั่วไปdecltypeทำงานแตกต่างกันไปขึ้นอยู่กับว่าคุณให้ชื่อตัวแปรหรืออย่างอื่น (นิพจน์โดยพลการ) decltype(a)ส่งคืนชนิดของตัวแปรa(เพราะคุณเพียงแค่ให้ชื่อตัวแปร) decltype((a))ในทางกลับกันให้ประเภทของการแสดงออก (a) (ซึ่งก็คือint) ด้วยการเพิ่มการอ้างอิงที่ระบุประเภทค่าของการแสดงออก [1/2]
HolyBlackCat

(a)(รวมถึงa) คือ lvalue ซึ่งถูกระบุด้วย&(xvalues ​​แสดงด้วยค่า&&prvalues ​​จะไม่เปลี่ยนชนิดเลย) เนื่องจากนิพจน์ไม่เคยมีประเภทการอ้างอิงความจริงที่decltypeสามารถเพิ่มการอ้างอิงถึงประเภทนั้นจึงไม่สามารถทำให้เกิดข้อขัดแย้งได้ [2/2]
HolyBlackCat

3

เป็นทางเลือกแทนคำตอบก่อนหน้านี้คุณสามารถใช้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));
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.