重载的函数模板从未被调用

发布于 2024-10-27 14:05:09 字数 3234 浏览 2 评论 0 原文

我喜欢模板,至少如果我能理解它们的话我会喜欢;-)。我使用模板实现了一个重载运算符。我现在正在尝试专门化函数调用。

这就是我所做的:

class Terminallog {
public:

    Terminallog();
    Terminallog(int);
    virtual ~Terminallog();

    template <class T>
    Terminallog & operator<<(const T &v);
    template <class T>
    Terminallog & operator<<(const std::vector<T> &v);
    template <class T>
    Terminallog & operator<<(const std::vector<T> *v);
    template <class T, size_t n>
    Terminallog & operator<<(const T(&v)[n]);
    Terminallog & operator<<(std::ostream&(*f)(std::ostream&));
    Terminallog & operator<<(const char v[]);

    //stripped code

};

//stripped code

template <class T>
Terminallog &Terminallog::operator<<(const T &v) {
    if (this->lineendet == true) {
        this->indent();
    }
    this->lineendet = false;
    std::cout << v;
    return *this;
}

template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> &v) {
    for (unsigned int i = 0; i < v.size(); i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v.at(i);
    }
    std::cout << std::flush;
    return *this;
}

template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> *v) {
    for (unsigned int i = 0; i < v->size(); i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v->at(i);
    }
    std::cout << std::flush;
    return *this;
}

template <class T, size_t n>
Terminallog &Terminallog::operator<<(const T(&v)[n]) {
    unsigned int elements = sizeof (v) / sizeof (v[0]);
    for (unsigned int i = 0; i < elements; i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v[i];
    }
    std::cout << std::flush;
    return *this;
}

inline
Terminallog &Terminallog::operator<<(std::ostream&(*f)(std::ostream&)) {
    if (f == static_cast<std::ostream & (*)(std::ostream&)> (std::endl)) {
        this->lineendet = true;
    }
    std::cout << f;
    return *this;
}

inline
Terminallog &Terminallog::operator<<(const char v[]) {
    if (this->lineendet == true) {
        std::cout << std::endl;
        this->indent();
        std::cout << v;
    }
    this->lineendet = false;
    std::cout << v;
    return *this;
}

//sripped code

现在我正在尝试类似的方法

vector<int> *test3 = new vector<int>;
    test3->push_back(1);
    test3->push_back(2);
    test3->push_back(3);
    test3->push_back(4);

Terminallog clog(3);
clog << test3;

,编译得很好。但是执行代码时,它会打印 test3 的地址,而不是所有元素。我的结论是编译器认为这

Terminallog & operator<<(const T &v);

是一个更好的匹配。但我不知道该怎么办。我的代码错误在哪里?为什么

Terminallog & operator<<(const std::vector<T> *v);

从不被调用?

I love templates, at least I would if I would understand them ;-). I implemented an overloaded operator using templates. I am now trying to specialise the function calls.

Here is what I do:

class Terminallog {
public:

    Terminallog();
    Terminallog(int);
    virtual ~Terminallog();

    template <class T>
    Terminallog & operator<<(const T &v);
    template <class T>
    Terminallog & operator<<(const std::vector<T> &v);
    template <class T>
    Terminallog & operator<<(const std::vector<T> *v);
    template <class T, size_t n>
    Terminallog & operator<<(const T(&v)[n]);
    Terminallog & operator<<(std::ostream&(*f)(std::ostream&));
    Terminallog & operator<<(const char v[]);

    //stripped code

};

//stripped code

template <class T>
Terminallog &Terminallog::operator<<(const T &v) {
    if (this->lineendet == true) {
        this->indent();
    }
    this->lineendet = false;
    std::cout << v;
    return *this;
}

template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> &v) {
    for (unsigned int i = 0; i < v.size(); i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v.at(i);
    }
    std::cout << std::flush;
    return *this;
}

template <class T>
Terminallog &Terminallog::operator<<(const std::vector<T> *v) {
    for (unsigned int i = 0; i < v->size(); i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v->at(i);
    }
    std::cout << std::flush;
    return *this;
}

template <class T, size_t n>
Terminallog &Terminallog::operator<<(const T(&v)[n]) {
    unsigned int elements = sizeof (v) / sizeof (v[0]);
    for (unsigned int i = 0; i < elements; i++) {
        std::cout << std::endl;
        this->indent();
        std::cout << i << ": " << v[i];
    }
    std::cout << std::flush;
    return *this;
}

inline
Terminallog &Terminallog::operator<<(std::ostream&(*f)(std::ostream&)) {
    if (f == static_cast<std::ostream & (*)(std::ostream&)> (std::endl)) {
        this->lineendet = true;
    }
    std::cout << f;
    return *this;
}

inline
Terminallog &Terminallog::operator<<(const char v[]) {
    if (this->lineendet == true) {
        std::cout << std::endl;
        this->indent();
        std::cout << v;
    }
    this->lineendet = false;
    std::cout << v;
    return *this;
}

//sripped code

Now I am trying something like

vector<int> *test3 = new vector<int>;
    test3->push_back(1);
    test3->push_back(2);
    test3->push_back(3);
    test3->push_back(4);

Terminallog clog(3);
clog << test3;

which compiles just fine. However executing the code, it prints the address of test3, instead all the elements. I conclude that the compiler thinks, that

Terminallog & operator<<(const T &v);

is a better match. However I don't know what to do about it. Where is the mistake in my code? Why is

Terminallog & operator<<(const std::vector<T> *v);

never called?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久随 2024-11-03 14:05:09

代码中 test3 的类型为 std::vector; *,但没有 Terminallog::operator<< 接受该类型的参数。有一个采用 const std::vector 。 * 如果你这样做了它就会被调用

clog << const_cast<const vector<int>*>(test3);

顺便说一句,新建一个向量几乎从来都不是一个好主意。

The type of test3 in your code is std::vector<int> *, but there is no Terminallog::operator<< that takes an argument of that type. There is one that takes const std::vector<int> * and it would be called if you did

clog << const_cast<const vector<int>*>(test3);

Incidentally, new'ing a vector is almost never a good idea.

平生欢 2024-11-03 14:05:09

为了匹配指向 const 向量的指针版本,需要将 const 添加到类型中,并且这不是顶级 const(const 指向向量的指针,即 std::vectorstd::vector T>* const)。所选择的重载不需要任何类型转换并且是更好的匹配。

我建议完全删除指针重载,特别是看到它只是复制向量引用重载。相反,只需取消引用指针即可。

clog << *test3;

For it to match the pointer-to-const-vector version, a const needs to be added to the type and this is not a top-level const (const-pointer-to-vector, i.e std::vector<T>* const). The chosen overload does not require any type conversions and is a better match.

I'd suggest completely removing the pointer overload, especially seeing that it just duplicates the vector reference overload. Instead just dereference the pointer.

clog << *test3;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文