C++受模板方法声明影响的名称查找
C++ name lookup affected by declaration of a template method
我不明白以下C++代码片段中需要static_cast(使用 GCC-4.7 测试):
#include <cstdio>
class Interface
{
public:
virtual void g(class C* intf) = 0;
virtual ~Interface() {}
};
class C
{
public:
void f(int& value)
{
printf("%dn", value);
}
void f(Interface* i)
{
i->g(this);
}
template <typename T>
void f(T& t);
//void f(class Implementation& i);
};
class Implementation : public Interface
{
public:
Implementation(int value_) : value(value_) {}
void g(C* intf)
{
intf->f(value);
}
private:
int value;
};
int main()
{
C a;
Implementation* b = new Implementation(1);
//a.f(b); // This won't work: undefined reference to `void C::f<Implementation*>(Implementation*&)'
a.f(static_cast<Interface*>(b));
delete b;
return 0;
}
如果我省略static_cast,我会收到链接器错误,因为它想要使用:
template <typename T>
void f(T& t);
而不是:
void f(Interface* i);
另一方面,如果我将模板化方法替换为以下内容(在上面的代码片段中注释掉):
void f(class Implementation& i);
然后我没有收到错误,我可以看到在运行时调用了"正确"方法(即:
void f(Interface* i);
)。
为什么模板方法的声明会影响名称查找?提前非常感谢,
当对a.f(b)
执行重载解析时,编译器会注意到两个事实:
首先,您尝试使用类型 Implementation*
的左值调用f
。
其次,重载集中有三个功能:C::f(int&)
和C::f(Interface*)
和C::f<Implementation*>(Implementation*&)
。请注意,包含template
,因为它的模板参数可以从调用它的参数中推断出来。
现在编译器开始检查哪个函数适合"最好":
-
C::f(int&)
根本不能用这个论点来称呼。 - 可以调用
C::f(Interface*)
,但需要一个标准转换(指向派生的指针 ->指向基的指针) - 无需任何转换即可调用
C::f<Implementation*>(Implementation*&)
因此,模板非常简单地最适合。但是,由于您没有为模板定义实现,因此链接器稍后会出现错误消息,指出它找不到您尝试调用的函数。
相关文章:
- 正在查找文档以获得PS4平台的C++中的设备信息
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中查找文件
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 查找最接近的大于当前数字的数字的索引
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 查找后更改类变量
- 使用正则表达式regex_search在字符串中查找字符串
- 使用gcc从静态链接的文件中查找可选符号
- 在C++中查找范围的长度
- 算法问题:查找从堆栈中弹出的所有序列
- 在Windows中查找扬声器输出的当前音量级别
- 如何在C++中使用X509证书模在令牌中查找私钥
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 在 for 循环中查找问题时遇到困难
- 影响格雷厄姆查找凸包算法的未知错误
- C++受模板方法声明影响的名称查找
- C++:这个磁盘查找会对性能造成很大的影响吗