【问题标题】:operator new inside namespace命名空间内的运算符 new
【发布时间】:2011-06-02 05:48:10
【问题描述】:
namespace X
{
  void* operator new (size_t);
}

给出错误信息:

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

gcc compiler bug 吗?在较旧的 gcc 版本中,它似乎正在工作。 任何想法,为什么不允许?

用例: 我只想为类允许自定义operator new/delete,并希望禁止全局new/operator。不是链接器错误,而是很容易捕获编译器错误;所以我编码了:

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

这适用于旧版本的 gcc,但不适用于新版本。

【问题讨论】:

标签: c++ namespaces new-operator compiler-bug


【解决方案1】:

这是不允许的,因为它没有意义。例如你有以下

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 的命名空间? C++ 无法推断出这一点。

【讨论】:

  • 我发布了一个用例。可能还有其他用例,其中一个可能希望仅在 namespace 范围内使用运算符。
  • 查看g++ bug report you referenced 上的讨论。这是标准所禁止的。
  • +1,同意@sharptooth(我之前就想过这个问题;但我将这个重载用于其他目的)
  • 有一种可能的方式,C++应该先寻找*ptr所属的命名空间。这是全局命名空间,因为ptr 的类型是int*。因此,delete 应该使用全局运算符。但是,对于namespace X { ... } 中的任何类,它应该首先检查X::operator new,如果不存在则使用全局::operator new。它是如此微不足道,如此明显!在 C++ 中不存在它绝对不足为奇。
【解决方案2】:

如果我们从标准中考虑这一部分,@Sharptooth 的回答会更有意义:

3.7.3.1 分配函数[basic.stc.dynamic.allocation]

[..] 分配函数应该是类成员函数或全局函数;如果分配函数在全局范围以外的命名空间范围内声明或在全局范围内声明为静态,则程序是格式错误的。 [..]

上述限制可能是出于@sharptooth 的回答所指出的原因。

【讨论】:

    猜你喜欢
    • 2012-01-01
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    相关资源
    最近更新 更多