嵌套名称说明符中的不完整类型名称

时间:2018-02-26 09:43:57

标签: c++ class friend

我有以下两个类,我想指定第二个类的一个方法作为第一个类的朋友,因为该方法可以访问它的变量。我在标题中尝试了以下内容:

class SequenceThreader;

enum MappingDirection {Nowhere, Forward, Backwards};

class SequenceMapping {
    friend void SequenceThreader::query_paths_to_fasta(std::ofstream& output_file) const;
private:
    seqID_t seq_id;
    int32_t first_seq_pos;
    int32_t last_seq_pos;
    sgNodeID_t node;
    int32_t first_node_pos;
    int32_t last_node_pos;
    int32_t matched_unique_kmers;
    uint64_t possible_unique_matches;
    uint64_t n_kmers_in_node;
    bool direction_will_continue(int32_t next_position) const;

public:
    SequenceMapping();
    bool operator==(const SequenceMapping &other);
    bool operator<(const SequenceMapping &other) const;
    friend std::ostream& operator<<(std::ostream& stream, const SequenceMapping& sm);
    void initiate_mapping(uint64_t sequence_id);
    bool ismatched();
    void start_new_mapping(const graphPosition& gpos, int32_t seqpos, const UniqueKmerIndex& counts);
    void extend(int32_t nodepos, int32_t seqpos);
    sgNodeID_t absnode() const;
    sgNodeID_t dirnode() const;
    int32_t n_unique_matches() const;
    MappingDirection node_direction() const;
    MappingDirection seq_direction() const;
    bool mapping_continues(const graphPosition& gpos) const;
    double POPUKM() const;
};

class SequenceThreader {
    typedef std::unordered_map<seqID_t, std::vector<SequenceMapping>> SequenceMappingStore;
    typedef std::unordered_map<seqID_t, std::vector<std::vector<SequenceMapping>>> SequenceMappingPathsStore;

private:
    SequenceGraph& sg;
    UniqueKmerIndex graph_kmer_index;

    uint8_t k;
    std::string query_seq_file;
    std::string output_prefix;
    uint64_t memory_limit;
    SequenceMappingStore mappings_of_sequence;
    SequenceMappingPathsStore paths_of_mappings_of_sequence;

    void map_sequences_from_file(uint64_t min_matches, const std::string& filename);
    std::set<SequenceGraphPath> all_unique_paths() const;
    void print_mapping_path_name(const std::vector<SequenceMapping>& path, std::ofstream& output_file) const;

public:
    explicit SequenceThreader(SequenceGraph &_sg, uint8_t _k = 31) : sg(_sg), k(_k), graph_kmer_index(sg, _k) {}

    void map_sequences(uint64_t min_matches, const std::string& filename, const std::string& output) {
        output_prefix = output;
        query_seq_file = filename;

        map_sequences_from_file(min_matches, filename);
    }

    void print_mappings() const;
    void mappings_paths();
    void print_paths() const;
    void graph_paths_to_fasta(std::ofstream& output_file) const;
    void query_paths_to_fasta(std::ofstream& output_file) const;
    void print_unique_paths_sizes(std::ofstream& output_file) const;
};

但是我收到了编译错误:

In file included from /Users/bward/github/bsg/src/sglib/SequenceThreader.cpp:8:
/Users/bward/github/bsg/src/sglib/SequenceThreader.h:22:17: error: incomplete type 'SequenceThreader' named in nested name specifier
    friend void SequenceThreader::query_paths_to_fasta(std::ofstream& output_file) const;

由于这里的朋友声明文档:http://en.cppreference.com/w/cpp/language/friend

,这让我很难过

friend char* X::foo(int); // members of other classes can be friends too这样的话很好。

我需要做些什么才能编译?

1 个答案:

答案 0 :(得分:3)

首先必须定义

SequenceThreader,只有前向声明是不够的。由于错误消息说SequenceThreader需要在此处完成,否则编译器无法知道SequenceThreader是否有一个名为query_paths_to_fasta的成员。

要解决此问题,您可以提前移动SequenceThreader的定义(并删除前向声明)。