c ++在类的函数中调用类定义之外的函数

时间:2016-10-15 19:59:50

标签: c++ variables scope

编辑: 我更新了代码,希望现在更具体。基本上我试图使用dlib库提取功能。我需要在函数get_features(它在类定义中)中使用哈希表vocab,但是我想在获取函数get_features之前将值赋给vocab,如代码中所示,这不起作用。类feature_extractor由dlib库定义。我是c ++和dlib的新手,我实际上不知道如何更好地构建我的问题。

现在我的代码具有以下结构:

#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中使用哈希表,而无需在get_features中调用getVocab?也就是说,在函数get_features之前为变量vocab赋值,并在函数内使用它。

我尝试在f2之前在类定义中调用f1并将哈希表分配给变量,但它似乎不起作用。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

对冲投注我理解你的问题,有很多方法你可以做到这一点。其中一个在下面:

  1. 定义备用默认构造函数。
  2. 在所述成员初始化列表中,从vocab的结果初始化getVocab()
  3. 就是这样。它看起来像这样:

    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 ...
    };
    

    先前的代码也将参与移动语义,这也可以减轻不必要的复制。

    或者,您可以在getVocab() static var中创建vocab对象,将函数结果声明为引用类型(可能是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;
    }
    

    这样做, getVocab()的所有用户将获得相同的对象引用。线程安全可能会成为一个问题,因此如果是这样的话,还需要额外的工作,但希望你能得到这个想法。您还可以将它与先前的方法结合起来,并使vocab成员变量成为const-reference而不是具体对象。在这种情况下,所有提取器将共享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 ...
    };
    

    正如我所说,有很多方法可以做到这一点。哪一个取决于哪种最适合您的使用模式。

答案 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();
    }

};

答案 2 :(得分:-1)

我不明白你有什么打算做但你可以在你的函数之外声明你的哈希表作为全局变量,这是不推荐的。