1

私は本(Accelerated C ++)を読んでいて、その本から自分でC++を学ぼうとして運動をしています。

今、私は次のコードが機能しない理由を理解しようとしています。

// analysis.cpp
void write_analysis(ostream& out, const string& name,
                    double analysis(const vector<Student_info>&),
                    const vector<Student_info>& did,
                    const vector<Student_info>& didnt)
{
  out << name << ":median(did) = " << analysis(did) <<
    ", median(didnt)=" << analysis(didnt) << endl;
}

template <double F(Student_info&)>
double generic_analysis(const vector<Student_info>& students)
{
    vector<double> grades;

    transform(students.begin(), students.end(),
          back_inserter(grades), F);
    return median(grades);
}
template<> double generic_analysis<grade_aux>(const vector<Student_info>& students);

double median_analysis(const vector<Student_info>& students)
{
    return generic_analysis<grade_aux>(students);
    // if not using template function, the code will be 
    // as following
    // vector<double> grades;

    // transform(students.begin(), students.end(),
    //           back_inserter(grades), grade_aux);
    // return median(grades);
}

analysis.cpp

// analysis.h
template <double F(const Student_info&)>
double generic_analysis(const std::vector<Student_info>&);

void write_analysis(std::ostream&, const std::string&,
                    double analysis(const std::vector<Student_info>&),
                    const std::vector<Student_info>&,
                    const std::vector<Student_info>&);

double grade_aux(const Student_info&);

double median_analysis(const std::vector<Student_info>&);

analysis.h

// main.cpp
int main()
{
  // students who did and didn't do all their homework
  vector<Student_info> did, didnt;

  // read the student records and partition them
  Student_info student;
  while (read(cin, student)) {
    did.push_back(student);
  }

  // do the analyses
  write_analysis(cout, "median", median_analysis, did, didnt);

  return 0;
}

main.cpp

// grade.cpp 
// compute a student's overall grade from midterm and final exam grades
// and homework grade
double grade(double midterm, double final, double homework)
{
  return 0.2 * midterm + 0.4 * final + 0.4 * homework;
}

double grade_aux(const Student_info& s)
{
  try {
    return grade(s);
  } catch (domain_error) {
    return grade(s.midterm, s.final, 0);
  }
}

grade.cpp

エラーメッセージは次のとおりです。

g ++ -Wall * .cpp -o main /tmp/ccbXbVcV.o:関数内 median_analysis(std::vector<Student_info, std::allocator<Student_info> > const&)': analysis.cpp:(.text+0x91): undefined reference todouble generic_analysis <&(grade_aux(Student_info const&))>(std :: vector> const&)'collect2:ldが1つの終了ステータスを返しました

一方、generic_analysisコードの宣言と定義をヘッダーファイル内に配置すると、機能します。誰かが理由を説明してください?

編集: 行を削除すると:

template<> double generic_analysis<average_grade>(const vector<Student_info>& students);

私が得た:

g ++ -Wall * .cpp -o main /tmp/cc3VhXKU.o:関数内median_analysis(std::vector<Student_info, std::allocator<Student_info> > const&)': analysis.cpp:(.text+0x91): undefined reference todouble generic_analysis <&(grade_aux(Student_info const&))>(std :: vector> const&)'collect2:ldが1つの終了ステータスを返しました

だから私はが必要なようですExplicit instantiation。次に、次の行を追加しました。

template double generic_analysis<grade_aux>(const vector<Student_info>&);

エラーメッセージは次のとおりです。

g ++ -Wall * .cpp -o main

analysis.cpp:'double generic_analysis(const std :: vector&)[with double(* F)(const Student_info&)= grade_aux]'のインスタンス化:

analysis.cpp:26:72:ここからインスタンス化analysis.cpp:26:72:エラー:'double generic_analysis(const std :: vector&)[with double(* F)(const Student_info&)=grade_aux]'の明示的なインスタンス化利用可能な定義がありません[-fpermissive]analysis.cpp:'double generic_analysis(const std :: vector&)[with double(* F)(const Student_info&)= grade_aux]'のインスタンス化:

analysis.cpp:26:72:ここからインスタンス化analysis.cpp:26:72:エラー:'double generic_analysis(const std :: vector&)[with double(* F)(const Student_info&)=grade_aux]'の明示的なインスタンス化利用可能な定義がありません[-fpermissive]analysis.cpp:'double generic_analysis(const std :: vector&)[with double(* F)(const Student_info&)= grade_aux]'のインスタンス化:

analysis.cpp:26:72:ここからインスタンス化analysis.cpp:26:72:エラー:'double generic_analysis(const std :: vector&)[with double(* F)(const Student_info&)=grade_aux]'の明示的なインスタンス化利用可能な定義がありません[-fpermissive]

4

2 に答える 2

2

あなたは以下を定義します:

template<> double generic_analysis<grade_aux>(const vector<Student_info>& students);

実装はどこにありますか?

関数のインスタンス化を強制しようとしている場合:

http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc16explicit_instantiation.htm

于 2012-05-13T03:41:35.773 に答える
1

あなたが宣言した

template<> double generic_analysis<grade_aux>(const vector<Student_info>& students);

しかし、どこにも定義していません。そのような明示的な特殊化を本当に意図している場合は、それを定義する必要があります (ただし、ヘッダーには含まれていない可能性があります)。

一方、プライマリ テンプレートgeneric_analysisを使用することが意図されている場合は、上記の特殊化を宣言する必要はありません。

于 2012-05-13T03:43:46.427 に答える