ข้อผิดพลาด: ไม่มีข้อโต้แย้งสำหรับ 'at' ที่ขึ้นอยู่กับพารามิเตอร์เทมเพลต ดังนั้นจึงต้องมีการประกาศ at

นู๋ นี่

ฉันกำลังพยายามรวบรวมโค้ดส่วนนี้จาก 'ภาษาการเขียนโปรแกรม C++' ของ Bjarne Stroustrup แต่ CodeBlocks ยังคงส่งข้อผิดพลาดนี้ให้ฉันต่อไป

รหัสนี้เกี่ยวกับการตรวจสอบช่วงอาร์เรย์ที่อยู่ในฟังก์ชันเวกเตอร์

นี่คือรหัส:

#include <iostream>
#include <vector>
#include <array>

using namespace std;

int i = 1000;

template<class T> class Vec : public vector<T>
{
public:
    Vec() : vector<T>() { }

    T& operator[] (int i) {return at(i); }
    const T& operator[] (int i) const {return at(i); }
    //The at() operation is a vector subscript operation 
    //that throws an exception of type out_of_range
    //if its argument is out of the vector's range.
};

Vec<Entry> phone_book(1000);

int main()
{

    return 0;
}

ข้อผิดพลาดที่ส่งคืนคือ:

  • ไม่มีข้อโต้แย้งสำหรับ 'at' ที่ขึ้นอยู่กับพารามิเตอร์เทมเพลต ดังนั้นจึงต้องมีการประกาศ 'at'
  • หมายเหตุ: (หากคุณใช้ '-fpermissive' G++ จะยอมรับรหัสของคุณ แต่การอนุญาตให้ใช้ชื่อที่ไม่ได้ประกาศนั้นเลิกใช้แล้ว
  • ในฟังก์ชันสมาชิก 'const T& โอเปอเรเตอร์[] (int i) const':
  • ไม่มีข้อโต้แย้งสำหรับ 'at' ที่ขึ้นอยู่กับพารามิเตอร์เทมเพลต ดังนั้นจึงต้องมีการประกาศ 'at'
  • ไม่มีการประกาศ 'รายการ' ในขอบเขตนี้
  • อาร์กิวเมนต์เทมเพลต 1 ไม่ถูกต้อง
  • ประเภทที่ไม่ถูกต้องในการประกาศก่อนโทเค็น '('

ใครสามารถอธิบายเรื่องนี้ให้ฉันฟังได้ไหม

นอกจากนี้ ฉันจะใช้สิ่งนี้ได้อย่างไรหากฉันจะไม่ใช้ 'using namespace std;'


person Bernardo Pliego-Garcia    schedule 01.04.2015    source แหล่งที่มา
comment
เมื่อสืบทอดจากคอนเทนเนอร์ stl คุณควรทราบว่าคอนเทนเนอร์เหล่านั้นไม่มีตัวทำลายเสมือน นี่อาจทำให้เกิดปัญหาเมื่อคลาสย่อยของคุณได้รับรีซอร์สที่ควรปล่อยให้เป็นอิสระใน destructor   -  person 463035818_is_not_a_number    schedule 01.04.2015
comment
คำถามสุดท้ายไม่สำคัญ: ให้เขียน std:: หน้าชื่อทุกชื่อที่มาจาก namespace std เช่น เขียน std::vector ทุกที่ หรือเขียน using std::vector หนึ่งครั้ง (แทนที่จะเป็น namespace เพียงระบุชื่อบุคคลทั้งหมดที่คุณใช้)   -  person MSalters    schedule 01.04.2015


คำตอบ (2)


แทนที่ at ด้วย vector<T>::at หรือ this->at

กฎสำหรับวิธีการค้นหาฟังก์ชันในเทมเพลตนั้นเข้มงวดกว่าตอนที่ออกแบบ C++ ในตอนแรก

ตอนนี้ วิธีการในฐานที่ขึ้นต่อกันจะถูกค้นหาเฉพาะเมื่อคุณ this-> ไม่เช่นนั้นจะถือว่าเป็นฟังก์ชันโกลบอล (หรือฐาน/คลาสที่ไม่ขึ้นอยู่กับท้องถิ่น/อื่นๆ)

สิ่งนี้สามารถช่วยหลีกเลี่ยงเหตุการณ์ไม่คาดคิดในทางปฏิบัติ โดยที่สิ่งที่คุณคิดว่าเป็นการเรียกเมธอดกลายเป็นการเรียกเมธอดทั่วโลก หรือการโทรทั่วโลกกลายเป็นการเรียกเมธอด นอกจากนี้ยังช่วยให้สามารถตรวจสอบเนื้อความของวิธีการเทมเพลตได้ก่อนหน้านี้

person Yakk - Adam Nevraumont    schedule 01.04.2015

นอกจากคำตอบของ Yakk แล้ว วิธีแก้ปัญหาอื่นก็คือการเพิ่ม

using vector<T>::at;

ถึง Vec โดยพื้นฐานแล้วจะเพิ่มลงในรายการฟังก์ชันที่ค้นหา

ด้วยวิธีนี้ at() สามารถใช้งานได้ตามปกติโดยไม่ต้องเติมคำนำหน้าด้วยประเภทคลาสพื้นฐานหรือ this->

person noma    schedule 08.03.2017