gpt4 book ai didi

c++ - 继承成员函数的模板参数推导

转载 作者:行者123 更新时间:2023-12-05 09:36:51 24 4
gpt4 key购买 nike

我为以下问题而苦苦挣扎,但由于某种原因太盲目而看不到(可能很明显的)解决方案:

我正在编写一个类来存储具有特定签名的可调用对象(作为该类的模板参数给出)。对于我的 MCVE,我省略了这部分并假设 void()因为这部分不是问题。

所以,为了注册一个可调用对象,我使用了这样的方法:

template <typename F>
void call(F &&func)
{
std::cout << "call(f()):\n";
func();
}

(对于 MCVE,我通过调用可调用对象替换了存储。)

为了方便,我加了第二种口味:

template <typename C>
void call(C *pObj, void(C::*pFunc)())
{
std::cout << "call(C *pObj, void(C::*pFunc)()):\n";
(pObj->*pFunc)();
}

用成员函数覆盖对象(匹配所需的签名)。

这只适用于成员函数定义在给定对象本身的类中的情况。如果成员函数被继承则失败。

这可能与模板和继承有关(后者在编译模板时不可解析)。

完成 MCVE:

#include <iostream>

template <typename F>
void call(F &&func)
{
std::cout << "call(f()):\n";
func();
}

template <typename C>
void call(C *pObj, void(C::*pFunc)())
{
std::cout << "call(C *pObj, void(C::*pFunc)()):\n";
(pObj->*pFunc)();
}

// Test:

#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__

void test() { std::cout << "test()\n"; }

struct TestBase {
void test() { std::cout << "TestBase::test()\n"; }
};

struct Test: TestBase {
#ifdef FIX
void test() { TestBase::test(); }
#endif // FIX
};

int main()
{
DEBUG(call(&test));
DEBUG(Test obj);
DEBUG(call((TestBase*)&obj, &TestBase::test));
DEBUG(call([&]() { obj.test(); }));
DEBUG(call<Test>(&obj, &Test::test));
DEBUG(call(&obj, &Test::test)); // <== PROBLEM! Doesn't work without -DFIX. :-(
}

Live Demo on coliru

而不是定义包装函数Test::test() , 我可能可以添加一些东西到 template <typename C> void call(C*, void(C::*)())让这个工作,但我无法想象会发生什么。

不用说template这不仅仅是我的力量……

我已经看过 std::invoke希望在那里找到灵感,但这也无济于事。


琐事:

在从星期天晚上到星期二早上一直在努力解决这个问题之后,我在不到 10 分钟的时间内得到了 3 个可行的解决方案。这令人印象深刻……

最佳答案

问题是如果 Test 没有 test&Test::test 的类型将是 void(测试库::*)()。然后模板推导失败,因为从第一个和第二个函数参数为模板参数 C 推导的类型发生冲突。

作为另一种解决方案,您可以在 std::type_identity 的帮助下从推导中排除第二个参数 pFunc (C++20 起)(利用 non-deduced context )。

template <typename C>
void call(C *pObj, void(std::type_identity_t<C>::*pFunc)())
{
std::cout << "call(C *pObj, void(C::*pFunc)()):\n";
(pObj->*pFunc)();
}

关于c++ - 继承成员函数的模板参数推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64871437/

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