【问题标题】:Understanding templates in c++了解 C++ 中的模板
【发布时间】:2015-07-03 10:05:37
【问题描述】:

我正在尝试运行以下程序,但它会产生编译错误:

#ifndef TEMPLATE_SUM_H_
#define TEMPLATE_SUM_H_

template<typename T>
class sum
{
  public:
    sum() {
      val_1 = 0;
      val_2 = 0;
    }
    sum(T a, T b) {
      val_1 = a;
      val_2 = b;
    }
    friend std::ostream& operator<<(std::ostream &, const sum<> &);

  private:
    T val_1, val_2;
    T result() const;
};

#endif

源文件:

include <iostream>
#include "inc/sum.h"

template<typename T>
T sum<T>::result() const {
   return (val_1 + val_2);
}

template<typename T>
std::ostream& operator<<(std::ostream& os, const sum<T>& obj) {
//std::ostream& operator<<(std::ostream& os, sum<T>& obj) {
  os << obj.result();
  return os;
}

int main()
{
    sum<int> int_obj(15, 15);
    sum<float> float_obj(5.2, 3.5);
    std::cout << "result of int = " << int_obj << std::endl;
    std::cout << "result of float = " << float_obj << std::endl;
    return 0;
}

使用g++ (4.4.3)编译会产生如下错误:

In file included from template.cpp:2:
inc/sum.h:18: error: wrong number of template arguments (0, should be 1)
inc/sum.h:5: error: provided for ‘template<class T> class sum’
template.cpp: In function ‘std::ostream& operator<<(std::ostream&, const sum<T>&) [with T = int]’:
template.cpp:20:   instantiated from here
template.cpp:5: error: ‘T sum<T>::result() const [with T = int]’ is private
template.cpp:12: error: within this context
template.cpp: In function ‘std::ostream& operator<<(std::ostream&, const sum<T>&) [with T = float]’:
template.cpp:21:   instantiated from here
template.cpp:5: error: ‘T sum<T>::result() const [with T = float]’ is private
template.cpp:12: error: within this context

1) 任何人都可以帮我找出错误吗? 另外请建议一些链接,我可以在其中找到有关如何在 C++ 中使用模板的简短绝对详细信息。

2) 我读到在头文件中声明的模板化函数/类,并单独定义容易出现链接错误。任何人都可以解释/详细说明这一点吗? 上面的例子中是否存在链接错误的可能性?

声明如下:

“如果在 .h 文件中声明了模板或内联函数,请在同一个文件中定义它。这些结构的定义必须包含在每个使用它们的 .cpp 文件中,否则程序可能会失败链接一些构建配置。”

这个例子可以用一些更简单的方法来完成,而不需要使用重载的运算符等。但我正在尝试学习/练习模板并尝试一些功能。

【问题讨论】:

  • 再看friend声明,sum&lt;&gt;什么?由于第一个错误,其他错误可能只是后续错误。
  • @JoachimPileborg 我想它会采用/使用类的模板声明。如果我使用它 sum 比它给出编译错误:` inc/sum.h:19: 警告:朋友声明 'std::ostream& operator &)' 声明了一个非模板函数 inc/sum.h:19: 注意: (如果这不是你想要的,请确保函数模板已经被声明并在函数名后面添加 ) /tmp/ cc1Ks86b.o:在函数main' .
  • @JoachimPileborg 感谢分享这个可疑的链接,它回答了我提出的所有问题。

标签: c++ templates


【解决方案1】:

friend 函数声明需要有一个单独的模板定义:

template<typename U>
friend std::ostream& operator<<(std::ostream &, const sum<U> &);

friend 声明不继承封闭类的模板参数。

【讨论】:

  • 确实解决了编译错误,能否解释一下为什么需要这个?
  • 希望澄清更多。
【解决方案2】:

一个简单的示例源,开始使用;

计算器.h

#ifndef CALCULATOR_H
#define CALCULATOR_H

template <class TYPE>
class Calculator{

public:
    Calculator();
    TYPE Sum(TYPE param1, TYPE param2);

};


/**
 * To avoid template related compilation error
 * when templates are used in header and source files
 *
 * This class file has been removed from the project-source file.
 * However, is present in the project folder
 * Gets compiled with the header-file (being included)
 */
#include "Calculator.cpp"

#endif

计算器.cpp

#include <iostream>
using namespace std;
#include "Calculator.h"


template <class TYPE>
Calculator<TYPE>::Calculator()
{
}

template <class TYPE>
TYPE Calculator<TYPE>::Sum(TYPE param1, TYPE param2){

    cout << "Calculator::sum" << endl;
    cout << param1 <<endl;
    cout << param2 <<endl;

    TYPE result = param1 + param2 ;

    return result;
}

Main.cpp

#include <iostream>
using namespace std;
#include "Calculator.h"

int main(int argc, const char * argv[]) {
    cout << "Hello, Calculator!\n";

    Calculator<int> cObj;
    int out = cObj.Sum(2,3);
    cout << "out : " << out << endl;

    Calculator<string> cObjS;
    string outS = cObjS.Sum("A", "B");
    cout << "outS : " << outS << endl;

    cout << "Bye, Calculator!\n";


    return 0;
}

另外,您可以参考post,了解如何保留模板源和头内容,了解如何修复编译和链接器问题(有原因)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    相关资源
    最近更新 更多