C++ return 个不同的对象

C++ return different objects

我有一个大问题.. 我想 select 通过包装器 class 存储服务。返回值必须是存储服务中的对象 class。我粘贴了我目前的做法。但到目前为止我的心态并没有奏效。

错误:

error: inconsistent deduction for auto return type: ‘SQL*’ and then ‘REDIS*’ return new REDIS();

最大的愿望是有一个定义结构的接口 class 和一些 "driver classes" 包含目标存储服务的所有必要操作。

我希望你有另一种方法,我该如何解决这个问题..

    #include <iostream>


class StorageTemplate {
    public:
        virtual bool UserhasSurName() = 0;
        virtual bool UserhasGivenName() = 0;
};

class SQL: public StorageTemplate {
    public:
        bool UserhasSurName() {
            //A SQL QUERY
            return true;
        }
        bool UserhasGivenName() {
            //AN ANOTHER SQL QUERY
            return true;
        }
};

class REDIS: public StorageTemplate {
    public:
        bool UserhasSurName() {
            //A REDIS CALL
            return false;
        }
        bool UserhasGivenName() {
            //A REDIS CALL
            return false;
        }
};


class controller {
    public:
        auto test(int select) {
            if( select == 1)
            {
                return new SQL(); 
            } else {
                return new REDIS();
            }
        }
};



int main(int argc, char const *argv[])
{
    controller cont;
    auto schnitzel = cont.test(1);
    auto mitzel = cont.test(2);
    std::cout << schnitzel->UserhasSurName() << std::endl;
    std::cout << mitzel->UserhasSurName() << std::endl;
}

在此代码中

auto test(int select) {
    if( select == 1)
    {
        return new SQL(); 
    } else {
        return new REDIS();
    }

auto 无法推导,因为它只匹配精确类型。所以即使 SQLREDIS 继承自 StorageTemplate,也不会推导出 StorageTemplate。你需要指定类型

StorageTemplate* test(int select) {
    if( select == 1)
    {
        return new SQL(); 
    } else {
        return new REDIS();
    }

错误return Auto in test(),是return两种不同的类型。更改 StorageTemplate*

class controller {
    public:
        StorageTemplate* test(int select) {
            if( select == 1)
            {
                return new SQL(); 
            } else {
                return new REDIS();
            }
        }
};

您面临的问题如下:考虑您的功能

auto test(int select) {
    if (select == 1) {
        return new SQL(); 
    } else {
        return new REDIS();
    }
}

如果您尝试评估 test(1) 这将扩展为

auto test(int select) {
    if (true) {
        return new SQL(); 
    } else {
        return new REDIS();
    }
}

导致类型错误!

我将向您展示三种解决问题的方法:

1.函数模板和if constexpr

制作 test 函数模板并使用 C++17 功能检查正确的类型 if constexpr:

template<typename T>
auto test() {
    if constexpr(std::is_same<T, SQL>::value) {
        return new SQL();
    } else {
        return new REDIS();
    }
}

像这样在main()中使用它:

int main(){
    controller cont;
    auto schnitzel = cont.test<SQL>();
    auto mitzel = cont.test<REDIS>();
    std::cout << schnitzel->UserhasSurName() << std::endl;
    std::cout << mitzel->UserhasSurName() << std::endl;
}

2。函数模板和std::unique_ptr

如果你想避免使用 if constexpr 你可以简单地 return 一个 std::unique_ptr 的实例而不是原始指针。这是首选的方式:

template<typename T>
auto test() {
    return std::unique_ptr<T>(new T);
}

或者您可以 return std::make_unique<T>()

3。返回基础实例 class

这是避免类型错误的最明显的解决方案:只是 return 基础 class 的一个实例。如上所述,这里首选使用智能指针的解决方案:

std::unique_ptr<StorageTemplate> test(const int select) {
    if (select == 1) {
        return std::make_unique<SQL>();
    } else {
        return std::make_unique<REDIS>();
    }
}

如果你真的想避免使用智能指针,只需使用像这样的原始指针:

StorageTemplate* test(const int select) {
    if (select == 1) {
        return new SQL();
    } else {
        return new REDIS();
    }
}