![](/img/trans.png)
[英]In C++, why isn't it possible to friend a template class member function using the template type of another class?
[英]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.