模板类C++符号范围搜索顺序不同
C++ symbol scope search order different for template and non-template class?
#include <iostream>
void foo()
{
std::cout << "global foo()" << std::endl;
}
struct A {
void foo()
{
std::cout << "A::foo()" << std::endl;
}
};
struct B : public A {
void call()
{
foo();
}
};
int main(int argc, char **argv )
{
B b;
b.call();
return 0;
}
这给出了预期的结果:
A::foo()
但是,在更改两行(B 类到模板)后:
#include <iostream>
void foo()
{
std::cout << "global foo()" << std::endl;
}
struct A {
void foo()
{
std::cout << "A::foo()" << std::endl;
}
};
template <typename T> // change here
struct B : public T {
void call()
{
foo();
}
};
int main(int argc, char **argv )
{
B<A> b; // and here
b.call();
return 0;
}
我得到意想不到的结果:
global foo()
使用this->
不是一种选择,因为我正在尝试创建"后备"机制。
你得到的是预期的结果。这在C++标准中称为"两阶段名称查找"。
模板内的名称分为两种类型:
从属 – 依赖于模板参数但未在模板中声明的名称。
非依赖 – 不依赖于模板参数的名称,以及模板本身的名称和在其中声明的名称。
当编译器尝试解析代码中的某个名称时,它首先确定该名称是否相关,解析过程源于这种区别。虽然非依赖名称是"正常"解析的 – 定义模板时,从属名称的解析发生在模板实例化点。
示例中B::call
foo();
是非依赖名称,因此在模板定义时将其解析为全局foo()
。
公认的答案解释了为什么您会看到这种行为,但没有解释如何实现您想要的"后备"行为。这可以使用 SFINAE 来完成,方法是引入一对成员模板重载,其中之一仅在基类具有名为 foo
的成员函数时才存在。
template <typename T>
struct B : T {
template <void (T::*)()> struct has_mem_fn {};
template <typename U> void call(has_mem_fn<&U::foo>*) {this->foo();}
template <typename U> void call(...) {foo();}
void call() {call<T>(0);}
};
struct X {};
int main()
{
B<A> ba;
ba.call(); // A::foo()
B<X> bx;
bx.call(); // global foo()
}
更新:我刚刚注意到您在另一个答案中的评论,您说您知道此方法,但由于必须支持功能失调的编译器而无法使用它。那样的话,恐怕你想要的恐怕是不可能的。
你需要特别告诉使用 T 类方法。
template <typename T>
struct B : public T {
void call()
{
T::foo();
}
};
但至于回退机制,你可以检查这个问题:是否可以编写一个模板来检查函数是否存在?
使用替换失败不是错误 (SFINAE),您可以检查 T 中foo
的方法,然后运行正确的方法。
相关文章:
- 链接库时的默认目录上的GCC或G 路径搜索顺序
- treap 中的轮换会违反它的堆排序或二叉搜索树顺序吗?
- 正在覆盖find_package的默认搜索顺序
- void类数组顺序和二进制搜索使用
- 按字母顺序对数组进行二分搜索和排序 C++.
- 通过索引快速搜索,并将插入顺序保持在C 中
- 二进制搜索树中按顺序遍历的复杂性(使用迭代器)
- 使用递归的顺序和预序遍历 - 二叉搜索树 C++
- 二进制搜索树顺序树显示
- std::ostringstream 运算符重载搜索顺序
- 顺序搜索查询
- 模板类C++符号范围搜索顺序不同
- 二进制搜索树,按顺序遍历,步骤3逻辑辅助
- 如何更改共享库的搜索顺序
- 命名空间搜索顺序
- 按顺序搜索boost::multi_index,按顺序获取下一个元素
- 如何使用双向搜索按字母顺序将随机字符串添加到数组中
- 我想要一个递归函数来检查使用二进制搜索数组的顺序
- 二叉搜索树-按顺序遍历
- 在名称空间中搜索名称时是否有任何顺序