如何从返回模板抽象类的函数返回指针?

问题描述 投票:0回答:1

我有 2 个类 BaseArrayList,它是一个抽象模板类和一个来自 BaseArrayList 的 ArrayList 派生类,我让用户输入他们想要的列表类型,但问题是我需要创建一个 BaseArrayList 指针来指向列表,但是如果我使用 if/switch 语句,那么它们不会在范围之外声明。

template <typename T>
class BaseArrayList{
public:
    virtual ~BaseArrayList(){};
    virtual void add(const T element) = 0;
    virtual void remove(const int index) = 0;
    virtual void get(const int index) const = 0;
    virtual void print() const = 0;
    virtual void fullPrint() const = 0;
};

template <typename T>
class ArrayList : public BaseArrayList<T>{
private:
    T *arr;
    int size;
    int capacity;
public:
    ArrayList(const unsigned int capacity){
        // constructor
    }
    ~ArrayList(){
        // desctructor
    }
    void add(const T element) override{
        // some code
    }
    void remove(const int index) override{
        // some code
    }
    void get(const int index) const override{
        // some code
    }
    void print() const override{
        // some code
    }
    void fullPrint() const override{
        // some code
    }
};

template <typename T>
BaseArrayList<T>* createArrayType(const unsigned int type){
    unsigned int capacity = inputCapacity();

    switch (type){
        case 1: return new ArrayList<int>(capacity); break;
        case 2: return new ArrayList<double>(capacity); break;
        case 3: return new ArrayList<char>(capacity); break;
        case 4: return new ArrayList<string>(capacity); break;
        default: return nullptr;
    }
}

int main(){
     unsigned int type = arrayType();

     BaseArrayList* list = createArrayType(type);
}

编译器显示 2 个错误:无法推导类模板参数,没有函数模板“createArrayType”的实例与参数列表匹配。

我可以为每种类型创建 4 个不同的指针,或者使用 if/switch 根据用户输入创建一个指针,但指针的范围仅在 if 内部,这是一个主要问题。 我尝试将 createArrayType 函数设为模板,但编译器抛出一个错误,表示它不知道要返回什么类型的指针。

c++ templates c++17
1个回答
0
投票

你正在尝试的是不可能的。

简而言之:你不能。函数的返回类型必须在编译时众所周知。事实上,尝试在具有自动返回类型的函数中返回不同类型,即使您使用模板,它也会给您带来编译器错误

你可以尝试这样的事情

#include <iostream>
#include <string>
#include <type_traits>
template <typename T>
class BaseArrayList {
public:
    virtual ~BaseArrayList() {};
    virtual void add(const T element) = 0;
    virtual void remove(const int index) = 0;
    virtual T get(const int index) const = 0;
    virtual void print() const = 0;
    virtual void fullPrint() const = 0;
};

template <typename T>
class ArrayList : public BaseArrayList<T> {
private:
    T* arr;
    int size;
    int capacity;

public:
    ArrayList(const unsigned int capacity) : size(0), capacity(capacity) {
        arr = new T[capacity];
    }

    ~ArrayList() {
        delete[] arr;
    }

    void add(const T element) override {
        if (size < capacity) {
            arr[size++] = element;
        } else {
            std::cout << "Array is full!" << std::endl;
        }
    }

    void remove(const int index) override {
        if (index >= 0 && index < size) {
            for (int i = index; i < size - 1; ++i) {
                arr[i] = arr[i + 1];
            }
            --size;
        } else {
            std::cout << "Invalid index!" << std::endl;
        }
    }

    T get(const int index) const override {
        if (index >= 0 && index < size) {
            return arr[index];
        } else {
            std::cout << "Invalid index!" << std::endl;
            return T();
        }
    }

    void print() const override {
        for (int i = 0; i < size; ++i) {
            std::cout << arr[i] << " ";
        }
        std::cout << std::endl;
    }

    void fullPrint() const override {
        for (int i = 0; i < capacity; ++i) {
            std::cout << arr[i] << " ";
        }
        std::cout << std::endl;
    }
};

template <typename T>
BaseArrayList<T>* createArrayType(const unsigned int capacity) {
    return new ArrayList<T>(capacity);
}

template <typename T>
unsigned int inputCapacity() {
    unsigned int capacity;
    std::cout << "Enter capacity: ";
    std::cin >> capacity;
    return capacity;
}

template <typename T>
int arrayType() {
    unsigned int type;
    std::cout << "1 > Int" << std::endl;
    std::cout << "2 > Double" << std::endl;
    std::cout << "3 > Char" << std::endl;
    std::cout << "4 > String" << std::endl;
    std::cout << "Enter array type (1-4): ";
    std::cin >> type;
    return type;
}

int main() {
    // Declare all the types
    BaseArrayList<int>* intList;
    BaseArrayList<double>* doubleList;
    BaseArrayList<char>* charList;
    BaseArrayList<std::string>* strList;
    // Ask for which type the user wants and then initiaze it
    unsigned int type = arrayType<int>();
    // Ask for capacity
    unsigned int capacity = inputCapacity<int>();
    if(type == 1){
        intList = createArrayType<int>(capacity);
        // do more stuff here
    } else if(type == 2){
        doubleList = createArrayType<double>(capacity);
        // do more stuff here
    } else if(type == 3){
        charList = createArrayType<char>(capacity);
        // do more stuff here
    } else if(type == 4){
        strList = createArrayType<std::string>(capacity);
        // do more stuff here
    }
    // exit application
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.