gpt4 book ai didi

C++ 指向派生类成员的指针

转载 作者:行者123 更新时间:2023-12-02 20:58:39 25 4
gpt4 key购买 nike

我不明白这里发生了什么。我有一个类Base,其中包含一个字段a。现在,我创建一个扩展 Base 的 Derived 类。我还有一个模板函数,它通过传递指向成员的模板参数来打印我们想要的字段。

#include <iostream>

class Base {
public:
Base(double a):a{a} {}
double a;
};

class Derived : public Base {
public:
Derived(double a) : Base(a) {}
};

template<double (Derived::*p)>
void print(Derived d) {
std::cout << d.*p;
}

int main() {
Derived d {10.0};
print<&Derived::a>(d);
}

问题是它不起作用,但如果我只使用基类:

template<double (Base::*p)>
void print(Base b) {
std::cout << b.*p;
}

int main() {
Base b {10.0};
print<&Base::a>(b);
}

它按预期工作并打印 10.0。我怎样才能让它与子类一起工作?

编译器说:

test.cpp:15:6: note:   template argument deduction/substitution failed:
test.cpp:21:23: error: could not convert template argument ‘&Base::a’ from ‘double Base::*’ to ‘double Derived::*’
print<&Derived::a>(d);

最佳答案

正如其他人解释了原因,我将解释解决方案:

template<typename T, double (T::*p)>
void print(T d) {
std::cout << d.*p;
}


int main() {
Derived d {10.0};
print<Base, &Base::a>(d);
}

https://gcc.godbolt.org/z/pM762f

我确信这不是您所希望的,但它比重载每个版本要好。但我认为最好是找到一种更好的方法来解决问题,因为我知道这里的代码不是您实际面临的问题,因为您可以只传递 double 本身而不是成员指针。

因此,请尝试在代码上下文中解决问题,而不是用这种方式。以下是一些可能解决您实际问题的想法(如果有的话):

  • 使用枚举
  • 如果不是太多,考虑一下 std::map
  • 您可以使用 lambda(它们现在是 constexpr,因此您也可以在模板中使用它们)
  • 考虑将 print 函数移至基类甚至派生类
  • 使用高阶函数(本质上太多 lambda 了:D)而不是整个面向对象的解决方案。

以及许多其他解决方案,其中大多数可能不会帮助您(因为我不知道您的代码的上下文)。

关于C++ 指向派生类成员的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59327638/

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