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

incomplete type name in nested name specifier

我有以下两个 class,我想将第二个 class 的方法之一指定为第一个方法的友元,以便该方法可以访问它的变量。我在 header 中尝试了以下内容:

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 没问题。

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

SequenceThreader 必须先定义,仅前向声明是不够的。由于错误信息说SequenceThreader这里需要是完整类型,否则编译器无法知道SequenceThreader是否有这样一个名为query_paths_to_fasta的成员。

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