i have a big problem.. I wonna select the Storage Service via a wrapper class. The returning value must be an object within the storage service class. I pasted my current approa
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();
}
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();
}
}
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();
}
}
};