iam*_*ind 5 c++ compiler-construction templates
查看以下测试代码:
template<class T> struct Wrap {};
template<typename T> inline
void fun (T *&Int) // **choice 1**
{}
template<typename T> inline
void fun (Wrap<T> *&Int) // **choice 2**
{}
int main()
{
int i = 6;
fun((char*&)(i)); // **call 1**
fun((Wrap<char>*&)(i)); // **call 2**
}
Run Code Online (Sandbox Code Playgroud)
当我在linux g ++中运行此代码时,它按预期工作.当使用char*&调用fun()时,它会直接调用选择1的函数.但是,当我们使用Wrap <char>*&调用fun()时,我感兴趣并且它调用了选项2.即使选择1和2都对第二次调用有效,编译器设法选择更好的竞争者 - >选择2 (因为它存在).
问题:是否保证,对于C++的任何其他编译器,将保留相同的行为?如果没有,那么还有其他选择让它具有确定性吗?
选择第二个选择因为它比第一个选择更专业,即T*&可以绑定到任何非临时选项T*,但Wrap<T>*&只能绑定到非临时选项Wrap<T>*.据我所知,这是标准的,应该是可移植的行为,但在实践中,当涉及到这类事物时,实际上是不可移植的,通常不是什么是标准的定义.
虽然代码可能看起来像模板专门化,但事实并非如此。该语言不允许部分模板函数专业化。这两个是不相关的模板,恰好是重载的。
编译器将使用通常的查找机制查找对的调用fun( (Wrap<char>*&) i ),将找到两个模板并确定存在两个潜在的重载:
template <typename T> void fun( T*& ); // with T == Wrap<char>
template <typename T> void fun( Wrap<T>*& ) // with T == char
Run Code Online (Sandbox Code Playgroud)
然后,重载解析将确定第二个是更好的匹配并将其实例化。这是由标准保证的,但要注意:它们不是相同的模板,而是不同的模板,您可能会遇到意外的结果。请参阅@LiKao 链接的文章以获取更多见解。