оператор new внутри пространства имен

namespace X
{
  void* operator new (size_t);
}

выдает сообщение об ошибке как:

error: ‘void* X::operator new(size_t)’ may not be declared within a namespace

Это ошибка компилятора gcc? В более старой версии gcc это работает. Любая идея, почему это не разрешено?

Случай использования: я хотел разрешить только пользовательские operator new/delete для классов и запретить глобальные new/operator. Вместо ошибки компоновщика было легко поймать ошибку компилятора; поэтому я закодировал:

namespace X {
  void* operator new (size_t);
}
using namespace X;

Это работало для старой версии gcc, но не для новой.


person iammilind    schedule 02.06.2011    source источник
comment
Дубликат stackoverflow.com/questions/1568168/testoperator-new?   -  person Nemo    schedule 02.06.2011
comment
Если вы хотите использовать собственный оператор для классов, дайте им общий базовый класс с этим пользовательским оператором.   -  person sharptooth    schedule 02.06.2011


Ответы (2)


Ответ @Sharptooth имеет больше смысла, если мы рассмотрим этот раздел из стандарта:

3.7.3.1 Функции распределения [basic.stc.dynamic.allocation]

[..] Функция распределения должна быть функцией-членом класса или глобальной функцией; программа неправильно сформирована, если функция распределения объявлена ​​в области пространства имен, отличной от глобальной области видимости, или объявлена ​​статической в ​​глобальной области видимости. [..]

Вышеупомянутое ограничение, вероятно, наложено именно по той причине, на которую указывает ответ @sharptooth.

person Alok Save    schedule 02.06.2011

Это запрещено, потому что это не имеет смысла. Например, у вас есть следующее

int* ptr = 0;

namespace X {
    void* operator new (size_t);
    void operator delete(void*);
    void f()
    {
       ptr = new int();
    }
}

void f()
{
    delete ptr;
    ptr = 0;
}

теперь, как ptr должно быть deleted - с глобальным пространством имен operator delete() или с конкретным для namespace X? У С++ нет возможности вывести это.

person sharptooth    schedule 02.06.2011
comment
Я опубликовал один вариант использования. Также может быть другой вариант использования, когда можно использовать его как оператор только в пределах области namespace. - person iammilind; 02.06.2011
comment
См. обсуждение в отчете об ошибках g++, на который вы ссылались. Это запрещено стандартом. - person Nemo; 02.06.2011
comment
+1, согласен с @sharptooth (я думал об этой проблеме раньше, но использовал эту перегрузку для какой-то другой цели) - person iammilind; 02.06.2011
comment
Существует возможный способ, C++ должен сначала искать пространство имен, которому принадлежит *ptr. Это глобальное пространство имен, поскольку тип ptr равен int*. Таким образом, delete должен использовать глобальный оператор. Но для любого класса в namespace X { ... } он должен сначала проверить наличие X::operator new и использовать глобальный ::operator new, если он не существует. Это так банально, так очевидно! Совершенно не удивительно, что его нет в C++. - person peterh; 14.08.2020