ปัญหาบางอย่างขณะเรียนรู้ STL

ฉันใช้ g++ ใน CodeBlocks IDE ใน Ubuntu ฉันยังใหม่กับ STL และบางส่วนของ C++

คำถามที่ 1: //ตอบแล้ว

std::istream_iterator< std::string > begin ( dictionaryFile );
std::istream_iterator< std::string > end;
std::vector< std::string> dictionary;
std::copy ( begin, end, std::back_inserter ( dictionary ) );

ถูกต้องแต่พอผมเปลี่ยน

std::istream_iterator< std::string > end;

เข้าไปข้างใน

std::istream_iterator< std::string > end();

คอมไพเลอร์บอกว่าไม่มีการเรียกใช้ฟังก์ชันที่ตรงกันที่บรรทัดที่สี่

คำถามที่ 2: //ขออภัย ฉันไม่ได้ทำให้ปัญหาชัดเจนในครั้งแรก

struct PS : std::pair< std::string, std::string > {
PS();
static struct FirstLess: std::binary_function< PS, PS, bool> {
    bool operator() ( const PS & p, const PS & q ) const {
        return p.first < q.first;
    }
} firstLess1; };


struct FirstLess: std::binary_function< PS, PS, bool> {
bool operator() ( const PS & p, const PS & q ) const {
    return p.first < q.first;
}} firstLess2;

โปรดทราบว่าข้อแตกต่างเพียงอย่างเดียวระหว่าง firstLess1 และ firstLess2 คือ firstLess1 ได้รับการประกาศใน PS

เมื่อฉันเรียกใช้ฟังก์ชัน:

k = std::find_if ( j + 1, finis, std::not1 ( std::bind1st ( PS::firstLess1, *j ) ) );

คอมไพเลอร์แจ้งข้อผิดพลาด 'การอ้างอิงที่ไม่ได้กำหนดไปยัง PS::firstLess1' ให้ฉัน แล้วฉันก็เปลี่ยนเป็น

k = std::find_if ( j + 1, finis, std::not1 ( std::bind1st ( firstLess2, *j ) ) );

แล้วมันก็ผ่านการคอมไพล์

ที่แปลกกว่านั้นคือในส่วนอื่นๆ ของโปรแกรม ฉันใช้ทั้งสองอย่าง

j = std::adjacent_find ( j , finis, PS::firstLess1 );
j = std::adjacent_find ( j , finis, firstLess2 );

และคอมไพเลอร์ไม่ได้แจ้งข้อผิดพลาดให้ฉัน


person user522829    schedule 28.11.2010    source แหล่งที่มา
comment
ตกลง. ฉันคิดวิธีแก้ปัญหาคำถามที่สองแล้ว (แต่ก็ยังไม่รู้ว่าทำไม) เพียงใช้ k = std::find_if ( j + 1, finis, std::not1 ( std::bind1st ( PS::FirstLess (), *เจ ) ) ); ไม่เป็นไรหรือคุณสามารถเพิ่ม const PS::FirstEqual PS::firstEqual1 = PS::FirstEqual(); หลังจากการประกาศ   -  person user522829    schedule 28.11.2010


คำตอบ (3)


std::istream_iterator< std::string > end(); C++ ตีความว่าเป็นการประกาศฟังก์ชันที่ชื่อ end ประเภทค่าส่งคืนคือ std::istream_iterator< std::string > และรายการอาร์กิวเมนต์ว่างเปล่า นั่นเป็นเหตุผลที่คุณได้รับข้อผิดพลาดดังกล่าว ใน C ++ เพื่อสร้างวัตถุใด ๆ โดยการเรียกตัวสร้างเริ่มต้นของคลาสนั้น คุณเพียงแค่ต้องทำสิ่งนี้ type_name variable_name; type_name variable_name(); จะถูกตีความว่าเป็นการประกาศฟังก์ชัน

person Mihran Hovsepyan    schedule 28.11.2010
comment
นี่คือสิ่งที่เราเรียกว่า การแยกวิเคราะห์ที่น่ารำคาญที่สุด - person In silico; 28.11.2010

A1: ตอบเพียงพอแล้ว
A2: เพิ่ม const ในการประกาศ firstLess หรือ กำหนดอ็อบเจ็กต์ firstLess ในไฟล์ cpp (ดู สิ่งนี้)

person smerlin    schedule 28.11.2010
comment
+1 สำหรับ กำหนดวัตถุ firstLess กล่าวคืออยู่ในขอบเขตที่ปิดล้อม (ดูบรรทัดบนสุดในหน้าที่เชื่อมโยง) ในกรณีนี้ การเพิ่ม const ไม่ได้สร้างความแตกต่าง เนื่องจากจะใช้ได้เฉพาะกับสมาชิกแบบคงที่ของประเภทอินทิกรัลเท่านั้น ไม่ใช่ struct (สิ่งที่น่าประหลาดใจก็คือคอมไพเลอร์อนุญาตให้เรียก adjacent_find() ได้) - person j_random_hacker; 28.11.2010
comment
@j_random_hacker: แก้ไขแล้ว แต่มันควรจะทำงานเฉพาะกับประเภทอินทิกรัลเท่านั้นหรือ? มันใช้ได้กับฉันด้วยโครงสร้าง POD เช่นกันในอดีต ... - person smerlin; 28.11.2010
comment
ฉันไม่รู้ :) ฉันบอกได้แค่ว่าไม่ควรคาดหวังให้ได้ผล แต่คอมไพเลอร์มีอิสระที่จะอนุญาตสิ่งใดก็ตามที่ไม่ขัดแย้งกับมาตรฐาน และฉันก็ไม่คิดว่าเป็นเช่นนั้น - person j_random_hacker; 28.11.2010

A1:

ออบเจ็กต์ที่ตัวเริ่มต้นเป็นชุดวงเล็บว่าง เช่น () จะต้องถูกเตรียมใช้งานด้วยค่า

[ หมายเหตุ: เนื่องจาก () ไม่ได้รับอนุญาตตามไวยากรณ์สำหรับตัวเริ่มต้น

X a ();

ไม่ใช่การประกาศวัตถุของคลาส X แต่เป็นการประกาศฟังก์ชันที่ไม่มีการโต้แย้งและส่งคืน X

แบบฟอร์ม () ได้รับอนุญาตในบริบทการเริ่มต้นอื่นๆ (5.3.4, 5.2.3, 12.6.2) — บันทึกท้าย ]

A2:

ฉันไม่แน่ใจจริงๆว่าคุณต้องการอะไร std::find_if และ std::adjacent_find ทำบางสิ่งที่แตกต่างไปจากเดิมอย่างสิ้นเชิง แต่อย่างไรก็ตาม นี่คือโค้ดการทำงานบางส่วนที่ได้รับแรงบันดาลใจจากโค้ดของคุณ

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

typedef std::pair<std::string, std::string> TwoStrings;

struct FirstLess : std::binary_function<TwoStrings, TwoStrings, bool>
{
    bool operator() (const TwoStrings& p, const TwoStrings& q) const {
        return p.first < q.first;
    }
};

int main()
{
    std::vector<TwoStrings> v;
    std::vector<TwoStrings>::iterator it;
    v.push_back(TwoStrings("4. Here's ", "Johnny"));
    v.push_back(TwoStrings("1. Here's ", "Johnny"));
    v.push_back(TwoStrings("2. Here's ", "Johnny"));
    v.push_back(TwoStrings("2. Here's ", "Johnny"));
    v.push_back(TwoStrings("3. Here's ", "Johnny"));

    it = std::adjacent_find(v.begin(), v.end(), FirstLess());
    std::cout << it->first << it->second << std::endl;

    it = std::find_if(v.begin() , v.end(), std::not1(std::bind1st(FirstLess(), *(v.begin()))));
    std::cout << it->first << it->second << std::endl;
}

A ผลลัพธ์คือ:

1. Here's Johnny
4. Here's Johnny
person Palmik    schedule 28.11.2010