【问题标题】:incomplete type name in nested name specifier嵌套名称说明符中的类型名称不完整
【发布时间】:2026-01-13 00:50:02
【问题描述】:

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

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 这样说就可以了。

我需要做什么才能编译?

【问题讨论】:

  • 啊啊啊!我看到编译器从我的前向 decl 中知道该类存在,但对它的 query_paths_to_fasta 方法一无所知。谢谢songyuanyao,要不要给个我能接受的答案?

标签: c++ class friend


【解决方案1】:

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

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

【讨论】: