gpt4 book ai didi

c++ - 模板更喜欢子类函数而不是更专业的继承函数

转载 作者:行者123 更新时间:2023-11-30 02:17:03 25 4
gpt4 key购买 nike

当我使用这样的代码时,我似乎得到了意想不到的结果:

class Base
{
public:
template <typename T>
bool operator <<(int(*fx)(T)) {
return true;
}
};
class Sub : public Base
{
public:
template <typename T>
bool operator <<(T t) {
return false;
}
};

int foo(int a) {
return a;
}

int main() {
bool test = Sub() << foo;
std::cout << "Used " << (test ? "Base" : "Sub") << " class function";
}

此代码将使用非常通用的子类函数,而不是 GCC 4.6.3 和 VS C++ v141 上的专用基类函数。

但我希望它做的更像这段代码:

class AClass
{
public:
template <typename T>
bool operator <<(int(*fx)(T)) {
return true;
}
template <typename T>
bool operator <<(T t) {
return false;
}
};

int foo(int a) {
return a;
}

int main() {
bool test = AClass() << foo;
std::cout << "Used " << (test ? "Specialized" : "Generic") << " class function";
}

另一方面,此代码将使用 GCC 4.6.3 和 VS C++ v141 上预期的专用函数。

这是我的问题:

  • 这是功能还是错误?
  • 有什么好的方法既能保持多类结构又能很好地跨类选择模板?

最佳答案

您看到的行为对于该示例是正确的。

当C++遇到二元运算符表达式A << B时, 它寻找三种函数和函数模板声明:

  • 通过成员名称查找表达式 A.operator<< 可以找到的函数

  • 将通过参数相关查找表达式 operator<<(A, B) 找到的函数

  • 一组虚拟声明来表示运算符的内置含义,例如 int operator<<(int, int);

通过重载解析过程运行以这种方式找到的全部组合函数集,以找到最佳重载。

您的示例中的问题是,在第一个项目符号中,成员名称查找结果 Sub().operator<<只包含Sub中的函数模板,而不是 Base 中的其他函数模板.这是派生类的正常“隐藏”规则:除非另有说明,否则派生类的任何成员都隐藏所有具有相同名称的继承成员 - 即使该名称是一个奇特的名称,如“operator<<”。

绕过隐藏的简单方法是添加 using declaration “取消隐藏”继承的成员:

class Sub : public Base
{
public:
template <typename T>
bool operator <<(T t) {
return false;
}
using Base::operator<<; // NOTE
};

modified example program然后打印“Used Base class function”,因为现在两个成员对于重载解析都是可见的,并且 Base::operator<<模板函数比 Sub::operator<< 更专业模板函数。

关于c++ - 模板更喜欢子类函数而不是更专业的继承函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54045927/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com