C ++:为什么在VS2005中的(模板)类中的(模板)类中识别为Inline Friend函数的运算符位置?
-
25-09-2019 - |
题
我继承了一个Visual Studio 6.0项目以转换为2005。它在下面包含了一个很棒的MyClass类,该端代码通过在其实例上调用新的位置而在任何地方使用(在此处大量简化):
#include <new>
#include <cstdio>
template<class T>
class MyClass {
public:
// This is what the author assumed would be called on placement new.
inline friend void* operator new(size_t u_size, MyClass<T>& mc) {
printf("MyClass friend placement new\n");
// ...
return 0;
}
// This is just to show koenig lookup works on normal functions.
inline friend void hello(MyClass<T>& mc) {
printf("Hello called with koenig lookup\n");
// ...
}
// This was part of the original class, gets called further below.
operator unsigned int*() {
printf("Converting for default placement new\n");
// ...
return 0;
}
};
/* This gets called in VS2005 if un-commented.
template<class T>
void* operator new(size_t u_size, MyClass<T>& mc) {
printf("MyClass placement new non-friend non-inline\n");
// ***
return 0;
}
*/
class DummyClass {
int a;
};
void testfunction() {
MyClass<DummyClass> mc;
hello(mc);
void* a = new(mc) DummyClass; // Placement new call
char c;
gets(&c);
}
当我在VS2005中运行“ testFunction()”时,在安置新呼叫中,操作员“ inline friend void* operator* operator* operator new(...)”在myclass中从未被调用。取而代之的是,“运算符UNSIGNED INT*()”被调用,结果被施加到void*,而默认位置运算符新建被调用(因此显示为默认位置的转换new new”)。
在vs6中,安置新调用的新呼叫“内联朋友void* operator new(...)”在myclass中(因此显示了“ cmyclass friend bergement new”),这是作者的意图,但随后vs6又在vs6中再次实现了内联朋友一种怪异的方式。
VS2005为什么使用与参数依赖的查找识别New New new?它使用参数识别Hello()函数(显示“ Hello with with Koenig lookup”),但它不适用于新的位置。
作为参考,这似乎是在MyClass模板模板的(但是我都为完整的缘故留下的)。另外,如果您在myclass之外取消宣传非朋友的“新运营商”,则在VS2005中被正确调用。
是什么赋予了?那里有错误吗?位置新的是与参数有关查找的特殊情况吗? VS2005是对还是错?这里的标准C ++是什么?
对于下线,我将使用非界朋友而不是内联,但这与前锋和所有人都丑陋,想首先问这笔交易是什么。
解决方案
问题在于,分配函数在全局范围中查找,它没有使用ADL查找。由于在类中定义的朋友函数从封闭范围内隐藏了,因此找不到该功能。
5.3.4/9:
如果新表达式从Unary ::操作员开始,则分配函数的名称在全局范围中查找。否则,如果分配的类型是类型T或其类型的类型,则分配函数的名称在T的范围中查找。如果此查找未能找到名称,或者分配的类型不是类型,则分配函数的名称在全局范围中查找。