c++ - 将 void* 作为函数参数传递会选择错误的重载
问题描述
看了一遍,并没有看到完全按照我所看到的方式谈论这个,所以就这样吧。
我有一个具有 7 个 Put() 重载的类来处理传递每个内置的原始类型以及一个 char* 和一个 void*。传递原语或 char* 时会选择正确的重载,但当我传递 void* 时,它会选择 char* 的重载。
该类还具有 7 个 Get() 重载,并返回一个布尔值以指示该条目是否不存在。所以我必须通过引用传递参数才能取回值(因此将void*更改为void*&)。当我添加对此 Get() 的调用时,构建会出现以下错误:
错误 C2664: 'bool A::Get(EntryId,bool &,int)' : 无法将参数 2 从 'MyType *' 转换为 'bool &'
所以编译器似乎认为 MyType* 与 bool& 匹配。我在调用中的参数之前添加了一个 (void*) 强制转换,我收到以下错误:
错误 C2664: 'bool A::Get(EntryId,bool &,int)' : 无法将参数 2 从 'void *' 转换为 'bool &'
据我所知,我可以定义一个函数签名来获取一个 void*&,所以我不确定为什么编译器没有选择这个选项?
代码示例如下所示。有人对这两个问题有提示吗(对于 Put() 和 Get())?我可以使用一种解决方法,但我只是想了解这里的问题。谢谢你的帮助。
class A
{
A();
// Puts
void Put(EntryId id, bool bVal);
void Put(EntryId id, int iVal);
void Put(EntryId id, long lVal);
void Put(EntryId id, double dVal);
void Put(EntryId id, const char * szVal);
void Put(EntryId id, void * pVal);
// Gets
bool Get(DataStoreId id, bool & bVal);
bool Get(DataStoreId id, int & iVal);
bool Get(DataStoreId id, long & lVal);
bool Get(DataStoreId id, double & dVal);
bool Get(DataStoreId id, char *& szVal);
bool Get(DataStoreId id, void *& pVal);
};
int main(int argc, void ** argv)
{
A myObj;
std::string * myString = new std::string("My string");
myObj.Put(ENTRY1, myString); // calls Put(EntryId id, const char * szVal);
myObj.Get(ENTRY1, myString); // compilation error for bool&
myObj.Get(ENTRY1, (void*)myString); // compilation error for bool&
}
解决方案
首先,如果你有错误的类型,并且错误告诉你你有错误的类型,请尝试使用正确的类型。
如果您使用函数期望的确切类型,那么您将调用该函数;否则它会找到它可以转换的那个。如果没有,那么您会收到错误消息。
对于“Put”函数,您的“std::string*”类型错误,无法转换为“const char*”,但编译器发现存在潜在匹配,因为它可以转换任何指针键入“无效*”。所以它正确地这样做了。
为了演示转换规则,我使用了一个简单的赋值,因此您可以在编译器中查看错误消息。只需取消注释“pchar = myString;”行 请注意“pvoid = mystring;” 不会产生错误。
#include <iostream>
#include <string>
void Put(int id, const char* szVal) { std::cout << "put const char*" << std::endl; }
void Put(int id, void* pVal) { std::cout << "put void*" << std::endl; }
void Get(int id, char*& szVal) { std::cout << "get const char*" << std::endl; }
void Get(int id, void*& pVal) { std::cout << "get void*" << std::endl; }
int main(int argc, void** argv)
{
char* pchar = nullptr;
void* pvoid = nullptr;
std::string* myString = new std::string("My string");
// pchar = myString;
pvoid = myString;
Put(1, myString);
Put(1, "const char *");
Get(1, pchar);
Get(1, pvoid);
}
放 void*
放 const char*
得到 const char*
得到 void*
免责声明:我正在回答这个问题,绝不支持这种 Get/Put 设计,尤其是不使用没有长度参数的 void*。
推荐阅读
- azure-bot-service - 将对象保存为自定义状态会删除复杂参数(Azure 机器人服务)
- javascript - 带有 scss 类的 Ionic 4 D3 样式
- r - 使用带有计数和百分比的 Plotly 在 R 中打开饼图/甜甜圈图
- scala - 这个 Scala 流如何使用 16 个线程?
- macos - OS X CMake:可使用替代包名称执行
- ruby - 如何运行最简单的单元测试
- c++ - 来自不同位置的数组输出的执行时间
- reactjs - 在 React Compoment 中有条件地使用 Gatsby Link
- javascript - 为什么调用api时必须返回函数,而在express(KeystoneJs)中调用视图控制器时却不能?
- javascript - Firestore.settings() 需要一个参数,但所有参数在文档中都是可选的?