首页 > 解决方案 > 将 void* 作为函数参数传递会选择错误的重载

问题描述

看了一遍,并没有看到完全按照我所看到的方式谈论这个,所以就这样吧。

我有一个具有 7 个 Put() 重载的类来处理传递每个内置的原始类型以及一个 char* 和一个 void*。传递原语或 char* 时会选择正确的重载,但当我传递 void* 时,它会选择 char* 的重载。

该类还具有 7 个 Get() 重载,并返回一个布尔值以指示该条目是否不存在。所以我必须通过引用传递参数才能取回值(因此将void*更改为v​​oid*&)。当我添加对此 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&
}

标签: c++void-pointers

解决方案


首先,如果你有错误的类型,并且错误告诉你你有错误的类型,请尝试使用正确的类型。

如果您使用函数期望的确切类型,那么您将调用该函数;否则它会找到它可以转换的那个。如果没有,那么您会收到错误消息。

对于“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*。


推荐阅读