c++ - 模板,为什么这样调用模板函数不起作用?

标签 c++ templates

我正在阅读一本书(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);
}

分析.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>&);

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

主要.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);
  }
}

等级.cpp

错误信息是:

g++ -Wall *.cpp -o main /tmp/ccbXbVcV.o: In function 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 returned 1 exit status

同时,当我将 generic_analysis 代码声明和定义放在头文件中时, 它会起作用。请有人解释为什么?

编辑: 删除行时:

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

我得到了:

g++ -Wall *.cpp -o main /tmp/cc3VhXKU.o: In function 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 returned 1 exit status

看来我需要一个 Explicit instantiation .然后我添加了以下行:

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

现在错误信息是:

g++ -Wall *.cpp -o main

analysis.cpp: In instantiation of ‘double generic_analysis(const std::vector&) [with double (* F)(const Student_info&) = grade_aux]’:

analysis.cpp:26:72: instantiated from here analysis.cpp:26:72: error: explicit instantiation of ‘double generic_analysis(const std::vector&) [with double (* F)(const Student_info&) = grade_aux]’ but no definition available [-fpermissive] analysis.cpp: In instantiation of ‘double generic_analysis(const std::vector&) [with double (* F)(const Student_info&) = grade_aux]’:

analysis.cpp:26:72: instantiated from here analysis.cpp:26:72: error: explicit instantiation of ‘double generic_analysis(const std::vector&) [with double (* F)(const Student_info&) = grade_aux]’ but no definition available [-fpermissive] analysis.cpp: In instantiation of ‘double generic_analysis(const std::vector&) [with double (* F)(const Student_info&) = grade_aux]’:

analysis.cpp:26:72: instantiated from here analysis.cpp:26:72: error: explicit instantiation of ‘double generic_analysis(const std::vector&) [with double (* F)(const Student_info&) = grade_aux]’ but no definition available [-fpermissive]

最佳答案

您定义:

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

关于c++ - 模板,为什么这样调用模板函数不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10569151/

相关文章:

c++ - 创建 3 个子进程并在指定秒数后退出它们

c++ - 如何在 macOS 上的 Qt 中使用 OpenMP 进行编译?

C++友元类映射

C++ 使用方括号和指向实例的指针

c++ - 如何创建一个 vector 来保存同一模板类的所有类型的元素

c++ - char* 和 char[N] 的模糊错误

c++ - 从迭代器推导出模板函数返回类型的值类型

c++ - 在没有 ICU 或 boost 的情况下规范化 C++ 中的 unicode 字符?

c++ - 是否有从其他模板参数推导出来的强制模板参数之类的东西?

c++ - 使模板类型更具体(T => Certain<X>)以帮助内容辅助