Я унаследовал проект 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);
}
Когда я запускаю "testfunction()" в VS2005, при вызове нового размещения оператор "inline friend void* operator new(...)" в MyClass никогда не вызывается. Вместо этого вызывается «operator unsigned int*()», результат приводится к void*, и вместо этого вызывается оператор размещения по умолчанию new (поэтому отображается «Преобразование для размещения по умолчанию new»).
В VS6 новое размещение вызывает «встроенный друг void* operator new(...)» в MyClass вместо этого (поэтому отображается «новое размещение друга CMyClass»), что и предполагалось автором, но затем снова VS6 реализует встроенных друзей в странный способ.
Почему VS2005 не распознает встроенный оператор размещения друзей new с использованием поиска, зависящего от аргумента? Он распознает функцию hello() с использованием аргументов (поэтому отображается сообщение «Hello, вызванное поиском koenig»), но не работает для размещения new.
Для справки: кажется, что это происходит независимо от того, является ли MyClass шаблонным или нет (но я оставил его шаблонным для полноты картины). Кроме того, если вы раскомментируете недружественный «новый оператор» за пределами MyClass, он будет правильно вызван в VS2005.
Что дает? Там ошибка? Является ли размещение new особым случаем поиска, зависящего от аргумента? VS2005 прав или нет? Что было бы здесь стандартным С++?
В качестве обходного пути я собирался использовать не встроенного друга вместо встроенного, но это становится уродливым с форвардами и всем остальным, я хотел сначала спросить, в чем здесь дело.
a + b
by13.3.1.2/3
). Как процитировал @avakar,new
не такой случай. - person Johannes Schaub - litb   schedule 07.03.2010