为什么在这两种情况下使用C ++模板存在差异?

时间:2016-03-30 20:25:56

标签: c++ templates

简单模板的头文件trivial_template.hpp。

// Import packages from the C++ STL
#include <string>
#include <cstring>
#include <stdio.h>
#include <utility>
#include <limits.h>         // For std::LONG_MIN

#ifndef __TRIVIAL_TEMPLATE_H
#define __TRIVIAL_TEMPLATE_H
using namespace std;

template <typename T>
class trivial_template {
    public:
        trivial_template();
        ~trivial_template();
        static bool is_non_negative(T a_num);
        T square_given_number(T a_num);
};
#endif

简单模板的实现文件,trivial_template.cpp。

#include "./trivial_template.hpp"

template <typename T>
trivial_template<T>::trivial_template() {
}

template <typename T>
trivial_template<T>::~trivial_template() {
}

template<typename T>
bool trivial_template<T>::is_non_negative(T a_num) {
    return (0 <= a_num);
}

template<typename T>
T trivial_template<T>::square_given_number(T a_num) {
    return (a_num*a_num);
}

使用它的C ++主文件。

#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include <math.h>
#include <climits>
#include <cfloat>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

#include "../../elements/trivial_template.hpp"

using namespace std;

int main(int argc, char *argv[]) {
    cout << "   ###" << trivial_template<int>::is_non_negative(493) << "===" << endl;
    trivial_template<int> *a_ptr;
    cout << "   ###" << a_ptr->square_given_number(5) << "===" << endl;
    // 0.25^2 = 0.0625
    trivial_template<long double> *b_ptr;
    cout << "   ###" << b_ptr->square_given_number(-0.25) << "===" << endl;
    // 16.25^2 = 164.0625
    cout << "   ###" << b_ptr->square_given_number(-16.25) << "===" << endl;
    return 0;
}

我编译,链接和运行它的命令是:

g++ -std=c++0x  -c  ../src/elements/trivial_template.cpp
g++ -std=c++0x  -c  ../src/test/temp/test_templates.cpp
g++ -std=c++0x  -o  ./test-boilerplate-code *.o

在链接过程中,会产生以下错误消息:

Undefined symbols for architecture x86_64:
  "trivial_template<long double>::square_given_number(long double)", referenced from:
      _main in test_templates.o
  "trivial_template<int>::is_non_negative(int)", referenced from:
      _main in test_templates.o
  "trivial_template<int>::square_given_number(int)", referenced from:
      _main in test_templates.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [template] Error 1

当我尝试使用不同路径获取C ++源文件位置的这个简单示例时,它可以工作。它的输出是:

    ###1===
    ###25===
    ###0.0625===
    ###264.062===
real         0.22
user         0.00
sys          0.00

为什么会出现这种差异?到底是怎么回事?

另外,请帮助我修复链接错误吗?

非常感谢,祝你有个美好的一天!

1 个答案:

答案 0 :(得分:2)

您必须将方法实现放在头文件中,并包含该文件。简而言之,模板必须在每个翻译单元中可见,就像任何声明一样。另外,为了防止多次包含,您应该在每个头文件中使用包含保护。

    /*template_declarations.hpp*/
    #ifndef TEMPLATE_DECLARATIONS_HPP
    #define TEMPLATE_DECLARATIONS_HPP

    // put your declarations here

    #endif //TEMPLATE_DECLARATIONS_HPP



    /*template_implementation.hpp*/
    #ifndef TEMPLATE_IMPLEMENTATION_HPP
    #define TEMPLATE_IMPLEMENTATION_HPP

    #include "template_declarations.hpp"

    // put your implementation here

    #endif //TEMPLATE_IMPLEMENTATION_HPP

现在,您可以只包含第二个标题,或者创建帮助标题:

    /*template.hpp*/
    #ifndef TEMPLATE_HPP
    #define TEMPLATE_HPP

    #include "template_declarations.hpp"

    #endif //TEMPLATE_HPP