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
无法推导,因为它只匹配精确类型。所以即使 SQL
和 REDIS
继承自 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();
}
}
我有一个大问题.. 我想 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
无法推导,因为它只匹配精确类型。所以即使 SQL
和 REDIS
继承自 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();
}
}