我继承了一个 Visual Studio 6.0 项目以转换为 2005。它包括这个奇妙的 MyClass 类,客户端代码通过在它的实例上调用placement new 在任何地方使用它(这里大大简化了):
#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()”时,在放置 new 调用时,MyClass 中的运算符“inline friend void* operator new(...)”永远不会被调用。取而代之的是,“operator unsigned int*()”被调用,结果被强制转换为 void*,并且默认的放置操作符 new 被调用(所以“转换为默认放置 new”被显示)。
在 VS6 中,placement new 改为在 MyClass 中调用“inline friend void* operator new(...)”(因此显示“CMyClass friend placement new”),这是作者的意图,但随后 VS6 在一种奇怪的方式。
为什么 VS2005 不能识别使用参数相关查找的内联友元放置运算符 new?它使用参数识别 hello() 函数(因此显示“使用 koenig 查找调用 Hello”),但它不适用于放置 new。
作为参考,无论 MyClass 是否被模板化,这似乎都会发生(但为了完整起见,我将其保留为模板化)。此外,如果您在 MyClass 之外取消注释非朋友“operator new”,则该操作在 VS2005 中会被正确调用。
是什么赋予了?里面有错误吗?新位置是依赖于参数的查找的特例吗?VS2005是对还是错?这里的标准 C++ 是什么?
对于一种解决方法,我打算使用非内联朋友而不是内联,但是对于前锋和所有人来说,这变得很难看,我想先问一下这里的交易是什么。