使用模板打印课程

时间:2018-08-22 15:32:40

标签: c++ c++11

打印出类的所有值时遇到问题

#include <iostream>

const int LENGTH = 5;

template <typename T1, typename T2>
class Test {
private:
  T1 a;
  T2 b;

public:
  void setData(T1 a, T2 b)
  {
   this->a = a;
   this->b = b;
  }
  T1 get_a() { return a; }
  T2 get_b() { return b; }
  T2 sum() const;
  Test operator*(const Test& t0);
  friend std::ostream& operator<<(std::ostream& output, const Test<T1, T2>& t0);
};

template <typename T1, typename T2>
T2 Test<T1, T2>::sum() const
{
  return a + b;
}

template <typename T1, typename T2>
Test<T1, T2> Test<T1, T2>::operator*(const Test& t0)
{
 Test<T1, T2> t;
 t.a = this->a * t0.a;
 t.b = this->b * t0.b;
 return t;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& output, const Test<T1, T2>& t0)
{
  output << t0.get_a() << ", " << t0.get_b() << std::endl;
  return output;
}

int main(int argc, char *argv[])
{
  Test<int, float> t1;
  t1.setData(3, 4.5);
  Test<int, float> t2;
  t2.setData(5, 6.7);
  Test<int, float> t3 = t1 * t2;
  std::cout << t1;
}

最后一行显示了一个错误“未定义对operator << ...的引用”。我认为该错误来自于该类的朋友功能,但我不知道如何解决。 任何人都可以帮助我。感谢您的支持,谢谢!

3 个答案:

答案 0 :(得分:2)

您的朋友声明说的是,对于类型为TestT1的{​​{1}}的任何特定实例,都有一个 non-template {{1 }}。 (g ++为此提供了有用的警告。)

但是您定义了模板函数,它与声明的函数不同。

您可以可以在类内定义运算符,或使其成为模板,但是由于您仅使用公共成员,因此这里根本不需要T2,因此您可以删除整个朋友声明。

答案 1 :(得分:1)

这符合

#include <iostream>

const int LENGTH = 5;

template <typename T1, typename T2>
class Test;

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& output, const Test<T1, T2>& t0)
{
  output << t0.get_a() << ", " << t0.get_b() << std::endl;
  return output;
}

template <typename T1, typename T2>
class Test {
private:
  T1 a;
  T2 b;

public:
  void setData(T1 a, T2 b)
  {
   this->a = a;
   this->b = b;
  }
  T1 get_a() const { return a; }
  T2 get_b() const { return b; }
  T2 sum() const;
  Test operator*(const Test& t0);
  friend std::ostream& operator<< <T1, T2>(std::ostream& output, const Test<T1, T2>& t0);
};

template <typename T1, typename T2>
T2 Test<T1, T2>::sum() const
{
  return a + b;
}

template <typename T1, typename T2>
Test<T1, T2> Test<T1, T2>::operator*(const Test& t0)
{
 Test<T1, T2> t;
 t.a = this->a * t0.a;
 t.b = this->b * t0.b;
 return t;
}

int main(int argc, char *argv[])
{
  Test<int, float> t1;
  t1.setData(3, 4.5);
  Test<int, float> t2;
  t2.setData(5, 6.7);
  Test<int, float> t3 = t1 * t2;
  std::cout << t1;
}

问题是该类期望使用非模板函数,因此未实例化模板函数,因此在链接时未找到该模板函数。

修改:

在朋友声明中明确指出,这是<T1, T2>

的专业化

将模板声明放在上面,否则将不会被实例化

operator<<的定义上方进行声明。

在吸气剂上添加缺少的const。

答案 2 :(得分:0)

这里是编译代码的编辑。我添加了const以获取方法,并删除了朋友std :: ostream&运算符<<< / p>

#include <iostream>

const int LENGTH = 5;

template <typename T1, typename T2>
class Test {
private:
    T1 a;
    T2 b;

public:
    void setData(T1 a, T2 b)
    {
        this->a = a;
        this->b = b;
    }
    T1 get_a() const { return a; }
    T2 get_b() const { return b; }
    T2 sum() const;
    Test operator*(const Test& t0);
};

template <typename T1, typename T2>
T2 Test<T1, T2>::sum() const
{
    return a + b;
}

template <typename T1, typename T2>
Test<T1, T2> Test<T1, T2>::operator*(const Test& t0)
{
    Test<T1, T2> t;
    t.a = this->a * t0.a;
    t.b = this->b * t0.b;
    return t;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& output, const Test<T1, T2>& t0)
{
    output << t0.get_a() << ", " << t0.get_b() << std::endl;
    return output;
}

int main(int argc, char *argv[])
{
    Test<int, float> t1;
    t1.setData(3, 4.5);
    Test<int, float> t2;
    t2.setData(5, 6.7);
    Test<int, float> t3 = t1 * t2;
    std::cout << t1;
}