在C++中解析函数/方法/模板名称的偏好是什么?

Pat*_*ick 2 c++ templates argument-dependent-lookup

如果有多种可能性,C++编译器如何决定调用哪个函数/方法?在我的具体情况下,我有C++运行时的标准自由函数,我也有一个模板化的免费变体,如下所示:

// The definitions of the C++ Run Time Library (from memory.h)
extern malloc(size_t s);
extern void free(void *p);

// Our own memory management functions
extern void *OurMalloc(size_t s);
extern void OurFree(void *p);

// Own variants to overrule malloc and free (instead of using #define)
template<typename T>
void *malloc(T t)
{
return OurMalloc(t);
}

template<typename T>
void free(T *t)
{
OurFree(t);
}
Run Code Online (Sandbox Code Playgroud)

我使用以下代码测试了这个:

void main(void)
{
void *p = malloc(10);
free(p);
}
Run Code Online (Sandbox Code Playgroud)

如果我编译并运行它,似乎对malloc的调用被模板化变量正确替换.到现在为止还挺好.

但是,对free的调用不会被模板化变量所取代,并且仍会调用标准C++函数.

C++编译器使用什么规则来决定哪个变体优先?这与Koenig查找规则有关吗?

注意:我尝试了这种替代方法,因为使用#define无法解决问题(请参阅问题如何使用C宏(#define)来改变调用而不是原型).

APr*_*mer 8

一般来说,过载分辨率非常复杂.

在您的情况下,这很容易:如果存在完全匹配,则不考虑函数模板.免费是这种情况(标准free取一个空*),对于malloc它不是(标准malloc取一个size_t,你传递一个int而size_t不能是int的typedef - size_t是unsigned ).如果使用void*以外的类型调用free,则应该实例化模板.

运行:

#include <iostream>

void* ml(size_t s)
{
    std::cout << "ml(size_t)\n";
}

void fr(void *p)
{
    std::cout << "fr(void*)\n";
}

template<typename T>
void* ml(T t)
{
    std::cout << "ml<" << typeid(T).name() << ">(T)\n";
}

template<typename T>
void fr(T *t)
{
    std::cout << "fr<" << typeid(T).name() << ">(T*)\n";
}

int main()
{
    void* p1 = ml((size_t)10);
    fr(p1);
    int* p2 = (int*)ml(10);
    fr(p2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我明白了

ml(size_t)
fr(void*)
ml<i>(T)
fr<i>(T*)
Run Code Online (Sandbox Code Playgroud)

我回来了 typeid(int).name()