C+;中函数/方法/模板名称解析的首选项是什么+;? 如果有多种可能性,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); }
如果我编译并运行它,那么对malloc的调用似乎被模板化变量正确地替换了。到目前为止,一切顺利C+;中函数/方法/模板名称解析的首选项是什么+;? 如果有多种可能性,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); },c++,templates,argument-dependent-lookup,C++,Templates,Argument Dependent Lookup,如果我编译并运行它,那么对malloc的调用似乎被模板化变量正确地替换了。到目前为止,一切顺利 但是,调用的自由并没有被模板化的变体所替代,标准的C++函数仍然被调用。 < C++编译器使用什么规则来决定哪一个变量优先? 这与Koenig查找规则有关吗 注意:我尝试了这个替代方法,因为使用#define并不能解决问题(请参见问题)。过载解决通常相当复杂 在您的例子中,这非常简单:如果存在精确匹配,则不考虑函数模板。对于free,情况就是这样(标准free取一个void*),对于malloc,情况
但是,调用的自由并没有被模板化的变体所替代,标准的C++函数仍然被调用。 < C++编译器使用什么规则来决定哪一个变量优先? 这与Koenig查找规则有关吗
注意:我尝试了这个替代方法,因为使用#define并不能解决问题(请参见问题)。过载解决通常相当复杂 在您的例子中,这非常简单:如果存在精确匹配,则不考虑函数模板。对于free,情况就是这样(标准free取一个void*),对于malloc,情况不是这样(标准malloc取一个size\u t,您传递的是int,size\u t不能是int的typedef——size\u t是无符号的)。如果您使用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;
}
#包括
空隙*ml(尺寸)
{
std::cout对于有关malloc
和free
的特定问题,问题是在调用malloc
时:
void *p = malloc(10);
参数10被类型化为int
,而运行时的malloc()
的签名调用未签名的参数。由于没有精确匹配,编译器更喜欢模板化的malloc
,在那里它可以创建精确匹配
当你打电话时:
free(p);
p
的类型是void*
,它与free()
的运行时签名完全匹配,因此编译器不必麻烦使用模板化的free它不可能“替换”标准的malloc
使用此技术。其他答案已经解释过,因为在malloc
调用中使用有符号值作为参数,所以模板版本恰好“赢”了标准版本,因为标准版本需要无符号参数
为了更好地说明这一点,我只想补充一点,如果在malloc
调用中提供unsigned int
或unsigned long
参数
void *p1 = malloc(10u);
void *p2 = malloc(10ul);
您会注意到,在其中一个调用中,malloc
的模板版本也不再“起作用”,取而代之的是调用标准版本,因为它更适合参数(前提是在您的平台上size\u t
定义为无符号int
或无符号long
)不是回答你提出的问题,而是回答你想做的事情:
如果你的系统可用,你可以使用LDYPROFLASE预加载一个你所建的具有MALLC和免费版本的库。那么它们肯定会被调用而不是标准版本。这是一个C问题还是一个C++问题?如果你使用模板,它必须是C++。但是它是用C标记的,你使用的是MalCube()。Fred Larson?C++ C++ C++:我已经把问题编辑成纯C++了,提问者可能因为MSC似乎把C和C++混淆了,所以可能会混淆。我实际上是在试图解决一个C MalOC/FILE问题。所以我最初使用了C标签。但是你说得对,它必须是C++。C++名字解析可能是C++中更复杂的方面之一。为了解决这个问题:任何对malloc的正确调用都应该使用sizeof,其结果类型(很可能)size\t
。基本上,这个想法太脆弱了,没有用处(希望所有对malloc的调用都使用错误的大小类型).Andrey,这取决于大小\u t是否未签名。这里,大小\u t是未签名的长度,因此您需要10ul才能获得匹配-这就是为什么我在回答中使用大小\u t而不是使用后缀的原因。感谢您的解释,尽管我希望有一个答案允许我体面地覆盖malloc和free。我不确定您想要实现什么。如果您想使用自己的malloc/free实现,这通常由标准库实现支持,并且可以在链接时实现。但是,您必须检查您的实现以获取相关信息。
free(p);
void *p1 = malloc(10u);
void *p2 = malloc(10ul);