C++:为什么 VS2005 中的(模板)类中的运算符放置 new 不被识别为内联友元函数?

标签 c++ inline new-operator friend

我继承了一个 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()”时,在 placement new 调用中,MyClass 中的运算符“inline friend void* operator new(...)”永远不会被调用。相反,调用“operator unsigned int*()”,将结果转换为 void*,并调用默认放置操作符 new(因此显示“Converting for default placement new”)。

在 VS6 中,placement new 在 MyClass 中调用“inline friend void* operator new(...)”(因此显示“CMyClass friend placement new”),这是作者的意图,但 VS6 再次实现以一种奇怪的方式内联好友。

为什么 VS2005 无法识别使用参数相关查找的内联 friend 放置运算符 new?它使用参数识别 hello() 函数(因此显示“Hello called with koenig lookup”),但它不适用于 placement new。

作为引用,无论 MyClass 是否模板化,这似乎都会发生(但为了完整起见,我将其保留为模板)。此外,如果您在 MyClass 之外取消对非好友“operator new”的注释,那么它会在 VS2005 中被正确调用。

什么给了?那里有错误吗? placement new 是参数相关查找的特例吗? VS2005对还是错?这里的标准 C++ 是什么?

作为解决方法,我打算使用一个非内联 friend 而不是内联 friend ,但是对于前锋和所有人来说这变得很丑陋,我想先问问这是怎么回事。

最佳答案

问题是分配函数是在全局范围内查找的,而不是使用 ADL 查找的。由于在类中定义的友元函数在封闭范围内是隐藏的,因此找不到该函数。

5.3.4/9:

If the new-expression begins with a unary :: operator, the allocation function’s name is looked up in the global scope. Otherwise, if the allocated type is a class type T or array thereof, the allocation function’s name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function’s name is looked up in the global scope.

关于C++:为什么 VS2005 中的(模板)类中的运算符放置 new 不被识别为内联友元函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2393817/

相关文章:

c++ - 如何在 LLVM IR 级别找到出现在两个特定基本 block 之间的所有基本 block ?

css - 我怎么能有这两个 <div >'s inside another <div>? When I make them <span>' s 它不起作用

html - 与仅链接到硬文件相比,为网站使用内联/base64 图像要快多少?

c++ - 使用两个参数但不进行赋值来调用 new 运算符

c++ - 二维字符指针数组 --> 段错误?

c++ - 证明 rand() 可以返回 0 的在线资源?

c++ - 如何修复 -Wsubobject-linkage 警告?

c++ - 确保只构建智能指针

c++ - 内联函数

c++ - 在 C++ 代码中使用 new/delete 而不是 malloc/free 时崩溃