私は 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 が呼び出されます (したがって、"Converting for default placement new" が表示されます)。
VS6 では、プレースメント new は代わりに MyClass で「インライン フレンド void* 演算子 new(...)」を呼び出します (したがって、「CMyClass フレンド プレースメント new」が表示されます)。これは作成者が意図したものですが、VS6 はインライン フレンドを奇妙な方法。
VS2005 が引数依存ルックアップを使用してインライン フレンド配置演算子 new を認識しないのはなぜですか? 引数を使用して hello() 関数を認識します (そのため、「koenig ルックアップで呼び出された Hello」が表示されます) が、新しい配置では機能しません。
参考までに、これは MyClass がテンプレート化されているかどうかに関係なく発生するようです (ただし、完全を期すためにテンプレート化したままにしています)。また、MyClass の外で非フレンドの「operator new」のコメントを外すと、VS2005 で適切に呼び出されます。
何を与える?そこにエラーはありますか?配置 new は、引数に依存するルックアップの特殊なケースですか? VS2005は正しいか間違っていますか? ここで標準 C++ とは何でしょう?
回避策として、インラインの代わりに非インラインのフレンドを使用するつもりでしたが、それはフォワードとすべてで醜くなり、最初にここで取引が何であるかを尋ねたかった.