Некоторые проблемы при обучении STL - PullRequest
3 голосов
/ 28 ноября 2010

Я использую g ++ в CodeBlocks IDE в 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 );

и компилятор не выдал мне ошибку.

Ответы [ 3 ]

4 голосов
/ 28 ноября 2010

std::istream_iterator< std::string > end(); C ++ интерпретирует это как объявление функции с именем end тип возвращаемого значения std::istream_iterator< std::string > и список аргументов пуст.Вот почему вы получаете такую ​​ошибку.В C ++ для создания любого объекта путем вызова конструктора по умолчанию его класса, вы просто должны сделать это type_name variable_name;.type_name variable_name(); будет интерпретироваться как объявление функции.

2 голосов
/ 28 ноября 2010

A1: уже достаточно ответили
A2: добавить const к объявлению firstLess, ИЛИ определить объект firstLess в файле cpp (см. this )

1 голос
/ 28 ноября 2010

A1:

Объект, инициализатором которого является пустой набор скобок, т. Е. (), Должен быть инициализирован значением.

[Примечание: поскольку () не являетсяразрешено синтаксисом для инициализатора,

X a ();

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

Форма () разрешена в некоторых других контекстах инициализации (5.3.4, 5.2.3, 12.6.2).- конец примечания]

A2:

Я не совсем уверен, что вы хотите, std :: find_if и std ::acent_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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...