2016-10-15 3 views
-2

EDIT: Я обновил код, надеюсь, теперь более конкретный. В основном я пытался извлечь функции с помощью библиотеки dlib. Мне нужно использовать hashtable vocab в функции get_features (которая находится внутри определения класса), но я хочу назначить значения вокабу до получения функции get_features, как указано в коде, что не работает. Класс feature_extractor определяется библиотекой dlib. Я новичок в C++ и dlib, и на самом деле я не знаю, как лучше сформулировать мой вопрос.C++ вызов функции вне определения класса в функции класса


Теперь мой код имеет следующую структуру:

#include <iostream> 

#include <dlib/svm_threaded.h> 

using namespace std; 
using namespace dlib; 

/* 
* Read a vocabulary file and return a map of vocab 
* ex. vocab["word-1"] = 0, vocab["word+0"] = 1, vocab["word+1"] = 2 
*/ 
std::map<std::string,int> getVocab() { 

    std::map<std::string, int> vocab; 
    std::vector<string> words; 

    ifstream infile("filename"); 
    string line; 
    while (getline(infile, line)) { 
     words.push_back(line); 
    } 
    int cnt = 0; 
    for (auto w : words) { 
     vocab[w] = cnt; 
     cnt++; 
     } 
    return vocab; 
    } 

class feature_extractor { 
public: 
    typedef std::vector<std::string> sequence_type; 

    std::map<std::string, int> vocab = getVocab(); // if put here, it does NOT work. 

    void get_features (
     feature_setter& set_feature, 
     const sequence_type& sentence, 
     unsigned long position 
    ) const 
    { 
    std::map<std::string, int> vocab = getVocab(); // if put here, it works. 
    set_feature(vocab[sentence[position]]); 
    } 


} 

int main() { 
    // other stuff 
    structural_sequence_segmentation_trainer<feature_extractor> trainer; 
    sequence_segmenter<feature_extractor> segmenter = trainer.train(samples, segments); 
    // other stuff 

} 

Есть ли способ, что я могу использовать хэш-таблицу в функции get_features без вызова getVocab внутри get_features? То есть, имея переменную vocab, она назначает значение перед функцией get_features и использует ее внутри функции.

Я попытался вызвать f1 в определении класса до f2 и присвоить хэш-таблицу переменной, но она не работает. Любая помощь будет принята с благодарностью.

+0

Почему это проголосовало? – Rodger

+3

@Rodger Почему вы его проголосовали? Любые хорошие рассуждения? –

+0

Да, это хороший вопрос. Я тоже не знаю, как это сделать. Код представлен, он будет иметь четкий ответ и т. Д. – Rodger

ответ

1

хеджирования ставки Я понимаю вашу проблему, Есть несколько способов, вы можете сделать это. Один из них ниже:

  1. Определите альтернативный конструктор по умолчанию.
  2. В списке инициализации члена из тех же, инициализировать vocab из результата getVocab().

Все. Это будет выглядеть примерно так:

class feature_extractor { 
public: 
    typedef std::vector<std::string> sequence_type; 

    std::map<std::string, int> vocab; 

    // constructor added here. 
    feature_extractor() : vocab(getVocab()) // <=== member initialized 
    { 
    } 

    // ... rest of your code ... 
}; 

Настоятель код будет участвовать в переездах семантике, а также, что должно облегчить ненужное копирование, а также.

В качестве альтернативы, вы можете сделать объект Vocab в getVocab() в статической вар, объявить результат функции в качестве референс-типа (вероятно const), и только загрузить файл сначала, если статический vocab.empty() верно. Такие, как:

std::map<std::string,int> const& getVocab() 
{ 
    static std::map<std::string, int> vocab; 

    if (vocab.empty()) 
    { 
     std::vector<std::string> words; 

     std::ifstream infile("filename"); 
     std::string line; 
     while (getline(infile, line)) { 
      words.push_back(line); 
     } 
     int cnt = 0; 
     for (auto w : words) { 
      vocab[w] = cnt; 
      cnt++; 
     } 
    } 
    return vocab; 
} 

Doing что, все пользователи getVocab() бы получить ту же ссылку на объект. Безопасность нитей может стать проблемой, поэтому потребуется дополнительная работа, если это так, но, надеюсь, вы получите эту идею. Вы также можете объединить это с предыдущими методами и сделать переменную-член vocab ссылкой на const-ссылку, а не конкретным объектом.В этом случае все экстракторы бы один и те же ссылки на тот же статический vocab в теле getVocab():

class feature_extractor { 
public: 
    typedef std::vector<std::string> sequence_type; 

    std::map<std::string, int> const& vocab; // note: reference 

    // constructor added here. 
    feature_extractor() : vocab(getVocab()) // <=== member initialized 
    { 
    } 

    // ... rest of your code ... 
}; 

Как я уже говорил, несколько способов сделать это. Какой из них зависит от того, что лучше всего подходит для вашего шаблона использования.

+0

Спасибо за предоставление нескольких решений. Я попробовал оба метода. Так или иначе, я должен инициализировать член внутри конструктора: 'feature_extractor() {vocab = getVocab();}' ... Но теперь он работает. – Hai

+0

@Hai Нет проблем. Синтаксис использования инициализации * member * показан в обоих приведенных мною примерах. Я бы предложил сделать это, особенно в последнем случае, когда это не предложение; он обязательно (ссылки должны всегда быть инициализированы *). Удачи. – WhozCraig

-1

Я не понимал, что вы склонны делать, но вы можете объявить свою хэш-таблицу вне своих функций глобальной переменной, которая не рекомендуется.

0

Я понял, что вы хотите использовать функцию getVocab для инициализации члена вашего класса feature_extractor. Вы можете сделать это в конструкторе (как было предложено WhozCraig). Вы также можете сделать функцию getVocab частью того же класса, если они логически связаны, и если вам нужна только она там, чтобы она не попадала в глобальное пространство имен. Как, например:

class feature_extractor { 

private: 

    std::map<std::string, int> getVocab() { 
     // your code 
    } 

public: 
    typedef std::vector<std::string> sequence_type; 

    std::map<std::string, int> vocab ; 

    feature_extractor() 
    { 
     vocab = getVocab(); 
    } 

}; 
+0

Спасибо. В конечном итоге я определил функцию внутри определения класса, а также использовал конструктор. – Hai

+0

Приветствую вас. –

Смежные вопросы