Назначение оператора new() указателю на функцию?

Я пытаюсь определить класс, которому можно передать функцию «распределителя объектов», и он принимает оператор объекта шаблона new() в качестве аргумента по умолчанию. У меня есть следующий код:

template<class _Obj>
class Foo
{
private:
    typedef _Obj (_Obj::*fp_alloc_type)();

public:
    Foo(fp_alloc_type t=_Obj::operator new ());

...
};

Это дает ошибку компилятора C2039: 'new' : не является членом 'SomeObj'

Разве компилятор не генерирует реализацию «нового» по умолчанию для объектов, которые не определяют свои собственные? Я что-то упускаю?


person jwalk    schedule 28.03.2013    source источник
comment
Да. Компилятор не генерирует operator new для вашего класса. Откуда вы взяли эту идею?   -  person Nawaz    schedule 28.03.2013
comment
Тогда почему я могу вызвать новый _Obj()? Разве это не _Obj::operator new()?   -  person jwalk    schedule 28.03.2013
comment
@jwalk, нет. Это глобальная новинка. ::operator new()   -  person StoryTeller - Unslander Monica    schedule 28.03.2013
comment
Разве в С++ еще нет класса распределителя? template < class T > class allocator   -  person andre    schedule 28.03.2013
comment
Этот предыдущий поток может быть полезен: stackoverflow.com/questions/1885849/   -  person Shafik Yaghmour    schedule 28.03.2013
comment
@StoryTeller Или нет. Здесь компилятор следует очень специфическим правилам поиска имени, которые немного отличаются от правил любой другой функции (поскольку они игнорируют любые пространства имен, содержащие класс). Но можно скрыть глобальный operator new. Конечно, если программист пишет ::new Foo, то он все равно будет использовать ::operator new().   -  person James Kanze    schedule 28.03.2013


Ответы (1)


Что бы это ни было, функция operator new не является нестатической функцией-членом любого класса. Даже если вы объявляете и определяете оператор нового класса, он считается статической функцией-членом; если он принимает один аргумент size_t, то указатель на него будет void* (*ptrToNew)( size_t ). (Если размещение новое, конечно, аргументов будет больше.)

Когда вы делаете new Foo, компилятор выполняет поиск имени в operator new сначала в области Foo (если Foo является типом класса), а затем в глобальном пространстве имен. (Интересно, что компилятор не будет искать пространство имен, в котором объявлено Foo. ADL никогда не применяется. Функция operator new в пространстве имен, отличном от глобального пространства имен, никогда не будет найдена.) Если вы не объявили operator new в классе, будет использоваться глобальная функция operator new.

person James Kanze    schedule 28.03.2013
comment
В качестве продолжения я предполагаю, что нет стандартного способа получить указатель на реализацию объекта нового оператора? - person jwalk; 28.03.2013
comment
@jwalk Объект не имеет реализации функции operator new. Если есть конкретный класс operator new, void* (*ptrNew)( size_t ) = &Foo::operator new должен работать. Если вы не знаете, существует ли конкретный класс operator new, вам понадобится какое-то метапрограммирование, чтобы узнать. Но зачем тебе это? - person James Kanze; 28.03.2013
comment
Мне было интересно написать реализацию шаблона пула объектов, который принимает необязательный аргумент в конструкторе для метода размещения объектов в пуле. - person jwalk; 28.03.2013