gpt4 book ai didi

c++ - 将重载的成员函数传递给函数模板

转载 作者:太空狗 更新时间:2023-10-29 20:33:47 25 4
gpt4 key购买 nike

我想要一个函数,它使用提供的可变输入参数调用给定的成员函数。我写了这样的东西:

#include <type_traits>
#include <utility>

struct A {
constexpr int show(int a, int b) const noexcept {return a + b;}
};

template <typename T, typename MemFn, typename ... Args>
int show(T && obj, MemFn Fn, Args&&... args)
{
return (obj.*Fn)(std::forward<Args>(args)...);
}

int main()
{
constexpr A a;
return show(a, &A::show, 1, 2);
}

它工作得很好,只要我在我的结构中只有一个 show 方法的定义。只要我添加类似的内容

struct A {
constexpr int show(int a, int b) const noexcept {return a + b;}
constexpr int show(int a) const noexcept {return a * 3;}
};

编译器无法推断出成员函数的类型,这确实很有意义,但我想知道是否有解决此问题的方法,例如将输入参数类型嵌入成员函数模板中或其他什么?

可以找到示例代码here .

最佳答案

这是一个令人讨厌的难题,它不断导致语言提案试图解决它(P0119P0834P1170)。

在那之前,如何包装对类型的特定成员函数的调用,其中该成员函数被重载或模板或采用默认参数,这个问题是相当困难的。

最简单的方法就是编写一个 lambda:

[](A& a, auto&&... args) -> decltype(a.show(FWD(args)...)) { return a.show(FWD(args)...); }

但这实际上并不那么容易,也不是特别方便 - 它实际上只处理 show 在非 const 上可调用的情况一个。如果我们有 const 和非 const 重载怎么办?还是 &&&

在我看来,最完整的实现方式是使用 Boost.HOFthis macro :

#define CLASS_MEMBER(T, mem) boost::hof::fix(boost::hof::first_of(\
boost::hof::match( \
[](auto, T& s, auto&&... args) \
BOOST_HOF_RETURNS(s.mem(FWD(args)...)), \
[](auto, T&& s, auto&&... args) \
BOOST_HOF_RETURNS(std::move(s).mem(FWD(args)...)), \
[](auto, T const&& s, auto&&... args) \
BOOST_HOF_RETURNS(std::move(s).mem(FWD(args)...)), \
[](auto, T const& s, auto&&... args) \
BOOST_HOF_RETURNS(s.mem(FWD(args)...))), \
[](auto self, auto&& this_, auto&&... args) \
BOOST_HOF_RETURNS(self(*FWD(this_), FWD(args)...)) \
))

在您的情况下,您需要:CLASS_MEMBER(A, show)。这将为您提供一个可以正确调用的函数对象:

auto show_fn = CLASS_MEMBER(A, show);
show_fn(a, 1); // ok, calls a.show(1)
show_fn(a, 1, 2); // ok, calls a.show(1, 2)
show_fn(a, 1, 2, 3); // error, no matching call - but sfinae friendly

关于c++ - 将重载的成员函数传递给函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53104399/

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