Некоторые проблемы при изучении STL

Я использую g++ в IDE CodeBlocks в Ubuntu. Я новичок в STL и некоторых частях C++.

Q1: //ответил

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();

компилятор говорит, что нет соответствующего вызова функции в четвертой строке.

Q2: //извините, я не объяснил проблему в первый раз

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 (), *j ) ) ); в порядке, или вы можете добавить 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: добавьте константу в объявление firstLess ИЛИ определите объект firstLess в файле cpp (см. это)

person smerlin    schedule 28.11.2010
comment
+1 за определение объекта firstLess, а именно в охватывающей области (см. верхнюю строку на связанной странице). В этом случае добавление const не имеет значения, так как это работает только для статических членов целочисленного типа, а не для структур. (Что удивительно, так это то, что компилятор разрешает вызов 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;
}

Выход:

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