试图在模板 class 中重载运算符 <<
Trying to overload operator<< in template class
(这是我当前课程的旧考试)
我试图在模板中重载 operator<< class 但是当我编译代码和 运行 程序时,我收到此消息:
/usr/bin/ld: /tmp/cc2BvB2u.o: in function `main':
/home/user/Skola/TDDI82/TENTA2017_1/UPPGIFT4/main.cpp:30: undefined reference to `operator<<(std::ostream&, Wrapper<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)'
/usr/bin/ld: /home/user/Skola/TDDI82/TENTA2017_1/UPPGIFT4/main.cpp:31: undefined reference to `operator<<(std::ostream&, Wrapper<int> const&)'
/usr/bin/ld: /home/user/Skola/TDDI82/TENTA2017_1/UPPGIFT4/main.cpp:32: undefined reference to `operator<<(std::ostream&, Wrapper<int> const&)'
collect2: error: ld returned 1 exit status
所有其他测试(我的 cout:s)都按照我的预期运行。在下面,我已经为该程序放置了所有代码。当我使用 friend 重载 operator<< 时,这不是问题。任何人都知道我做错了什么以及如何解决它?
//wrapper.h
#ifndef WRAPPER_H
#define WRAPPER_H
#include <ostream>
template<typename T>
class Wrapper
{
public:
Wrapper();
Wrapper(T const&);
Wrapper(Wrapper const&);
T get_value() const;
void set_value(T const& v);
Wrapper& operator=(T const& rhs);
friend std::ostream& operator<<(std::ostream& os, typename Wrapper<T>::Wrapper const& w);
private:
T value;
};
template<typename T>
std::ostream& operator<<(std::ostream& os, typename Wrapper<T>::Wrapper const& w);
#include "wrapper.tcc"
#endif
//wrapper.tcc
#ifndef WRAPPER_TCC
#define WRAPPER_TCC
#include "wrapper.h"
template<typename T>
Wrapper<T>::Wrapper()
: value{}
{}
template<typename T>
Wrapper<T>::Wrapper(T const& t)
: value{t}
{}
template<typename T>
Wrapper<T>::Wrapper(Wrapper const& w)
{
*this = w;
}
template<typename T>
T Wrapper<T>::get_value() const
{
return value;
}
template<typename T>
void Wrapper<T>::set_value(T const& v)
{
value = v;
}
template<typename T>
typename Wrapper<T>::Wrapper& Wrapper<T>::operator=(T const& rhs)
{
value = rhs;
return *this;
}
template<typename T>
std::ostream& operator<<(std::ostream& os, typename Wrapper<T>::Wrapper const& w)
{
os << w.get_value();
return os;
}
#endif
//main.cpp
#include "wrapper.h"
#include <stream>
#include <string>
int main()
{
//test
Wrapper<std::string> w1{"hej"};
Wrapper<int> w2{3};
Wrapper<int> w3{w2};
std::cout << w1.get_value() << std::endl;
std::cout << w2.get_value() << std::endl;
std::cout << w3.get_value() << std::endl;
w1.set_value("nej");
w2.set_value(10);
w3.set_value(20);
std::cout << w1.get_value() << std::endl;
std::cout << w2.get_value() << std::endl;
std::cout << w3.get_value() << std::endl;
w3 = w2;
w1 = "men...";
std::cout << w1.get_value() << std::endl;
std::cout << w2.get_value() << std::endl;
std::cout << w3.get_value() << std::endl;
w1 = "jo..";
w2 = 42;
std::cout << w1;
std::cout << w2;
std::cout << w3;
//
return 0;
}
感谢您花时间解决这个问题!
您的代码几乎没有问题。
- 缺少构造函数
template<typename T>
Wrapper<T>::Wrapper(T const& w): value(w){ }
Wrapper<T>::Wrapper
是一个构造函数就没什么意义了。 Wrapper<T>::Wrapper
不会因为 SFINAE 引发任何错误
std::ostream& operator<<(std::ostream& os, Wrapper<T> const& w){ ... }
- Return
Wrapper<T>&
而不是 Wrapper<T>::Wrapper
Wrapper<T>& Wrapper<T>::operator=(T const& rhs) { ... }
std::cout
定义在 iostream
在 When is typename
required
上查看此答案
(这是我当前课程的旧考试)
我试图在模板中重载 operator<< class 但是当我编译代码和 运行 程序时,我收到此消息:
/usr/bin/ld: /tmp/cc2BvB2u.o: in function `main':
/home/user/Skola/TDDI82/TENTA2017_1/UPPGIFT4/main.cpp:30: undefined reference to `operator<<(std::ostream&, Wrapper<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)'
/usr/bin/ld: /home/user/Skola/TDDI82/TENTA2017_1/UPPGIFT4/main.cpp:31: undefined reference to `operator<<(std::ostream&, Wrapper<int> const&)'
/usr/bin/ld: /home/user/Skola/TDDI82/TENTA2017_1/UPPGIFT4/main.cpp:32: undefined reference to `operator<<(std::ostream&, Wrapper<int> const&)'
collect2: error: ld returned 1 exit status
所有其他测试(我的 cout:s)都按照我的预期运行。在下面,我已经为该程序放置了所有代码。当我使用 friend 重载 operator<< 时,这不是问题。任何人都知道我做错了什么以及如何解决它?
//wrapper.h
#ifndef WRAPPER_H
#define WRAPPER_H
#include <ostream>
template<typename T>
class Wrapper
{
public:
Wrapper();
Wrapper(T const&);
Wrapper(Wrapper const&);
T get_value() const;
void set_value(T const& v);
Wrapper& operator=(T const& rhs);
friend std::ostream& operator<<(std::ostream& os, typename Wrapper<T>::Wrapper const& w);
private:
T value;
};
template<typename T>
std::ostream& operator<<(std::ostream& os, typename Wrapper<T>::Wrapper const& w);
#include "wrapper.tcc"
#endif
//wrapper.tcc
#ifndef WRAPPER_TCC
#define WRAPPER_TCC
#include "wrapper.h"
template<typename T>
Wrapper<T>::Wrapper()
: value{}
{}
template<typename T>
Wrapper<T>::Wrapper(T const& t)
: value{t}
{}
template<typename T>
Wrapper<T>::Wrapper(Wrapper const& w)
{
*this = w;
}
template<typename T>
T Wrapper<T>::get_value() const
{
return value;
}
template<typename T>
void Wrapper<T>::set_value(T const& v)
{
value = v;
}
template<typename T>
typename Wrapper<T>::Wrapper& Wrapper<T>::operator=(T const& rhs)
{
value = rhs;
return *this;
}
template<typename T>
std::ostream& operator<<(std::ostream& os, typename Wrapper<T>::Wrapper const& w)
{
os << w.get_value();
return os;
}
#endif
//main.cpp
#include "wrapper.h"
#include <stream>
#include <string>
int main()
{
//test
Wrapper<std::string> w1{"hej"};
Wrapper<int> w2{3};
Wrapper<int> w3{w2};
std::cout << w1.get_value() << std::endl;
std::cout << w2.get_value() << std::endl;
std::cout << w3.get_value() << std::endl;
w1.set_value("nej");
w2.set_value(10);
w3.set_value(20);
std::cout << w1.get_value() << std::endl;
std::cout << w2.get_value() << std::endl;
std::cout << w3.get_value() << std::endl;
w3 = w2;
w1 = "men...";
std::cout << w1.get_value() << std::endl;
std::cout << w2.get_value() << std::endl;
std::cout << w3.get_value() << std::endl;
w1 = "jo..";
w2 = 42;
std::cout << w1;
std::cout << w2;
std::cout << w3;
//
return 0;
}
感谢您花时间解决这个问题!
您的代码几乎没有问题。
- 缺少构造函数
template<typename T>
Wrapper<T>::Wrapper(T const& w): value(w){ }
Wrapper<T>::Wrapper
是一个构造函数就没什么意义了。Wrapper<T>::Wrapper
不会因为 SFINAE 引发任何错误
std::ostream& operator<<(std::ostream& os, Wrapper<T> const& w){ ... }
- Return
Wrapper<T>&
而不是Wrapper<T>::Wrapper
Wrapper<T>& Wrapper<T>::operator=(T const& rhs) { ... }
std::cout
定义在iostream
在 When is typename
required