C ++:为什么在VS2005中的(模板)类中的(模板)类中识别为Inline Friend函数的运算符位置?

StackOverflow https://stackoverflow.com/questions/2393817

我继承了一个Visual Studio 6.0项目以转换为2005。它在下面包含了一个很棒的MyClass类,该端代码通过在其实例上调用新的位置而在任何地方使用(在此处大量简化):

#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()”时,在安置新呼叫中,操作员“ inline friend void* operator* operator* operator new(...)”在myclass中从未被调用。取而代之的是,“运算符UNSIGNED INT*()”被调用,结果被施加到void*,而默认位置运算符新建被调用(因此显示为默认位置的转换new new”)。

在vs6中,安置新调用的新呼叫“内联朋友void* operator new(...)”在myclass中(因此显示了“ cmyclass friend bergement new”),这是作者的意图,但随后vs6又在vs6中再次实现了内联朋友一种怪异的方式。

VS2005为什么使用与参数依赖的查找识别New New new?它使用参数识别Hello()函数(显示“ Hello with with Koenig lookup”),但它不适用于新的位置。

作为参考,这似乎是在MyClass模板模板的(但是我都为完整的缘故留下的)。另外,如果您在myclass之外取消宣传非朋友的“新运营商”,则在VS2005中被正确调用。

是什么赋予了?那里有错误吗?位置新的是与参数有关查找的特殊情况吗? VS2005是对还是错?这里的标准C ++是什么?

对于下线,我将使用非界朋友而不是内联,但这与前锋和所有人都丑陋,想首先问这笔交易是什么。

有帮助吗?

解决方案

问题在于,分配函数在全局范围中查找,它没有使用ADL查找。由于在类中定义的朋友函数从封闭范围内隐藏了,因此找不到该功能。

5.3.4/9:

如果新表达式从Unary ::操作员开始,则分配函数的名称在全局范围中查找。否则,如果分配的类型是类型T或其类型的类型,则分配函数的名称在T的范围中查找。如果此查找未能找到名称,或者分配的类型不是类型,则分配函数的名称在全局范围中查找。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top