繁体   English   中英

C ++:为什么在VS2005的(模板)类中,操作符放置新功能不被识别为内联友元函数?

[英]C++: Why isn't operator placement new recognized as an inline friend function in a (template) class in VS2005?

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

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

为什么VS2005不使用依赖于参数的查找识别内联朋友放置运算符new? 它使用参数识别hello()函数(因此显示“使用koenig lookup调用Hello”),但它不适用于新的放置。

作为参考,无论MyClass是否被模板化,这似乎都会发生(但我为了完整性而将其模板化)。 此外,如果您取消注释MyClass之外的非朋友“operator new”,那么在VS2005中可以正确调用该朋友。

是什么赋予了? 那里有错误吗? placement new是依赖于参数的查找的特例吗? VS2005是对还是错? 这里标准的C ++是什么?

对于一个解决方法,我打算使用非内联的朋友而不是内联,但是前锋和所有人都会变得丑陋,想先问问这笔交易是什么。

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

5.3.4 / 9:

如果new-expression以unary :: operator开头,则在全局范围中查找分配函数的名称。 否则,如果分配的类型是类类型T或其数组,则在T的范围内查找分配函数的名称。如果此查找未能找到名称,或者如果分配的类型不是类类型,则分配函数的名称在全局范围内查找。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM