调用模板功能而不<"类型名称">

Calling template funсtion without <'typename'>

本文关键字:类型 gt 调用 lt 功能      更新时间:2023-10-16

我正在创建带有模板的不同类型的双链表。

这是标题和主代码。

#ifndef UNV_LIST
#define UNV_LIST
#include <typeinfo>
using namespace std;
class node_base{
    public:
        node_base *next;
        node_base *prev;
        node_base () { next = 0; prev = 0; }
        virtual int get_node_size () = 0;
};
template <typename T>
class node : public node_base{
    public:
        T data;
        node (const T& val) : data(val) {}
        virtual int get_node_size () { return sizeof (data); }
        T getData () { return data; }
};
class unvlist{
        node_base *head;
    public:
        int len;
        unvlist ();
        template <typename T> unvlist (const T* arr, int n);
        ~unvlist ();
        template <typename T> void set (int n, const T& val);
        template <typename T> T get (int n);
        template <typename T> T insert (int n, const T& val);
        void erase (int n);
        int size ();
        void pop_back ();
        void pop_front ();
        template <typename T> void push_back (const T& val);
        template <typename T> void push_front (const T& val);
};
unvlist :: unvlist (){
    head = 0;
    len = 0;
}
/* I want to use this function without <> */
template <typename T>
T unvlist :: get (int n){
    T retval;
    if (n >= len || n < 0){
        cout << "'In unvlist::get'-> Out of Bound!!!" << endl;
        return 0;
    }
    if (n >= 0){
        node_base *h = head;
        for (int i = 0; i < n; i++) { h = h->next; }
        retval = static_cast<node<T>*>(h)->getData ();
        cout << retval << endl;
    }
    return retval;
}
template <typename T>
void unvlist :: push_back (const T& val){
    node_base *n = new node<T> (val);
    if (head == NULL){
        head = n;
        len++;
    }else{
        node_base *h = head;
        while (h->next != NULL) { h = h->next; }
        h->next = n;
        n->prev = h;
        len++;
    }
}
template <typename T>
void unvlist :: push_front (const T& val){
    node_base *n = new node<T> (val);
    if (head == NULL){
        head = n;
        len++;
    }else{
        head->prev = n;
        n->next = head;
        head = n;
        len++;
    }
}
#endif

和main.cpp

#include <iostream>
#include "unvlist.hpp"
using namespace std;
int main (){
    unvlist *l1 = new unvlist ();
    l1->push_back<string> ("aa");
    l1->push_back<char> ('A');
    l1->push_back<float> (1.2345);
    l1->push_front<int> (11);
    for (int i = 0; i < 4; i++){
        cout << l1->get (i) << endl;  //The problem is here...
    }   cout << endl;
    return 0;
}

我必须在没有显式<>的情况下使用模板函数'Tget(int n)'。然而,当我编译它时,有一些错误。。。

g++ -std=c++11 -Wall  main.cpp  -o main
main.cpp: In function 'int main()'
main.cpp:16:21: error: no matching function for call to 'unvlist::get(int&)'
    cout << l1->get (i) << endl;
                      ^
main.cpp:16:21: note: candidate is:
In file included from main.cpp:3:0:
unvlist.hpp:44:27: note: template<class T> T unvlist::get(int)
   template <typename T> T get (int n);
                           ^
unvlist.hpp:44:27: note:   template argument deduction/substitution failed:
main.cpp:16:21: note:   couldn't deduce template parameter 'T'
    cout << l1->get (i) << endl;
                      ^
make: *** [all] Error 1

"push_back"answers"push_front"函数运行良好,但问题是"T get"函数。。。有没有一种方法可以在不使用<>的情况下使用'Tget'函数?

我必须在没有显式<>的情况下使用模板函数'Tget(int n)'

嗯,你不能。

没有任何参数与T有关,所以编译器无法知道你想让它做什么。它无法读懂你的想法。

无法导出函数的模板参数T的类型

T unvlist::get(int i)

具有这样的呼叫CCD_ 2。

你可以修改你的getter如下:

template <typename T>
void unvlist :: get (int n, T &retval){
    if (n >= len || n < 0){
        cout << "'In unvlist::get'-> Out of Bound!!!" << endl;
    }
    if (n >= 0){
        node_base *h = head;
        for (int i = 0; i < n; i++) { h = h->next; }
        retval = static_cast<node<T>*>(h)->getData ();
    }
}

并与先验已知的结果类型一起使用:

int main (){
    unvlist *l1 = new unvlist ();
    l1->push_back<string> ("aa");
    l1->push_back<string> ("A");
    for (int i = 0; i < 2; i++){
        std::string result;  // we know std::string in advance
        l1->get(i, result);  // here compiler derives the T type correctly
        std::cout << result << std::endl;
    }   cout << endl;
    return 0;
}

就严格回答您的问题而言,没有;编译器需要知道您要调用的get版本。

然而,你可以实现你想要做的事情。如果get通过引用(或指针)返回node_base,并且node_base有一个为每个节点重写的虚拟运算符>>,那么类型问题就消失了。

如果您认为node_base类是一个不应该公开的实现细节,那么您可以创建另一个类以供get返回(同样是一个具有特定类型派生类的基类)。