C++ return different objects

亡梦爱人 提交于 2019-12-02 13:34:20

The problem you are facing is the following: Consider your function

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

If you trying to evaluate test(1) this expands to

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

which results in a type error!

I show you three workarounds for your problem:

1. Function template and if constexpr

Make test a function template and check for the correct type using the C++17 feature if constexpr:

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

Use it in main() like this:

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. Function template and std::unique_ptr

If you want to avoid using the if constexpr you can simply return an instance of std::unique_ptr instead of a raw pointer. This is the preferred way to do:

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

Alternatively you can just return std::make_unique<T>().

3. Returning an instance of the base class

This is is most obvious solution to avoid the type error: Just return an instance of the base class. As above a solution using smart pointers is preferred here:

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

If you really want to avoid using smart pointers just use raw ones like this:

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

in this code

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

auto can't be deduced because it only match to exact type. so even if SQL and REDIS inherite from StorageTemplate, StorageTemplate won't be deduced. you need to spécifie the type

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

Error return Auto in test(),it's return two different types. Change by StorageTemplate*

class controller {
    public:
        StorageTemplate* test(int select) {
            if( select == 1)
            {
                return new SQL(); 
            } else {
                return new REDIS();
            }
        }
};
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!