【问题标题】:Trying to overload operator<< in template class试图在模板类中重载 operator<<
【发布时间】:2021-05-28 14:11:59
【问题描述】:

(这是我当前课程的旧考试)

我试图在模板类中重载运算符

/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)都按照我的预期进行。在下面,我已经为这个程序放了我所有的代码。当我使用朋友重载 operator

//包装器.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;
}

感谢您花时间解决这个问题!

【问题讨论】:

    标签: c++ templates operator-overloading


    【解决方案1】:

    您的代码几乎没有问题。

    • 缺少构造函数
    template<typename T>
    Wrapper<T>::Wrapper(T const& w): value(w){ }
    
    • Wrapper&lt;T&gt;::Wrapper 是一个构造函数 没有任何意义。 Wrapper&lt;T&gt;::Wrapper 不会因为 SFINAE 而引发任何错误
    std::ostream& operator<<(std::ostream& os, Wrapper<T> const& w){ ... }
    
    • 返回Wrapper&lt;T&gt;&amp; 而不是Wrapper&lt;T&gt;::Wrapper
    Wrapper<T>& Wrapper<T>::operator=(T const& rhs) { ... }
    
    • std::cout 定义在 iostream

    Link to the demo

    When is typename required查看这个答案

    【讨论】:

    • afaik 构造函数没有名称,Wrapper&lt;T&gt;::Wrapper 只是......没什么意义
    • 我已经实现了以 T 作为参数的构造函数。感谢其他更正,但我仍然收到“未定义的参考...”错误。
    • @463035818_is_not_a_number 有道理,SFINAE 在这里开始我想如果我没记错的话。
    • @exer240 你检查过这个链接吗godbolt.org/z/xnaTcd567
    • 谢谢,我错过了“template 朋友 std::ostream& operator const& w);”部分。现在可以了,再次感谢!但是我不明白它为什么起作用。你有什么好的链接可以让我阅读吗?
    猜你喜欢
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多