gpt4 book ai didi

c++ - 使用经典重载解析规则创建依赖于 std::invoke 的重载集类

转载 作者:行者123 更新时间:2023-11-28 04:52:02 24 4
gpt4 key购买 nike

我想设计一个类:

template <class... F> class overload_set;

它将在构造时采用可调用列表,并将有一个 operator() 将应用经典的重载决议规则来决定调用哪个函数。

对于两个函数,这将是这样的:

template <class F0, class F1>
struct overload_set: F0, F1
{
constexpr overload_set(F0 f0, F1 f1): F0(f0), F1(f1) {}
using F0::operator();
using F1::operator();
};

但是,这只适用于函数对象,而我希望它适用于任何使用 std::invoke 的可调用对象(自由函数、仿函数、lambda、函数成员、成员.. .).我当然希望它能够处理函数成员的 ref/const 限定的所有子项,例如:

struct subtle
{
constexpr void operator()() noexcept {}
constexpr void operator()() & noexcept {}
constexpr void operator()() && noexcept {}
constexpr void operator()() const& noexcept {}
constexpr void operator()() const&& noexcept {}
};

如果将 subtle 传递给 overload_set,它应该可以正常工作。

是否有可能在 C++17 中创建这样一个类 overload_set,如果可以,如何创建(根据需要使用尽可能多的模板元编程技巧,但尽可能少的 C 宏(希望没有) )?

最佳答案

实现@KerrekSB 所说的

template<typename F>
struct functor
{
using type = F;
};

template<bool Noexcept, typename R, typename... Args>
struct functor<R (*)(Args...) noexcept(Noexcept)>
{
struct fn
{
R (*p)(Args...) noexcept(Noexcept);
R operator()(Args&&... args) const noexcept(Noexcept)
{
return p(std::forward<Args>(args)...);
}
};
using type = fn;
};

template<typename F>
using func = typename functor<std::decay_t<F>>::type;

template<typename... Fs>
struct over : func<Fs>...
{
template<typename... Gs>
over(Gs&&... gs) : func<Fs>{std::forward<Gs>(gs)}... {}

using func<Fs>::operator()...;
};

template<typename... Gs>
auto makeover(Gs&&... gs)
{
return over<func<Gs>...>{std::forward<Gs>(gs)...};
}

你把它当作

int main()
{
auto o = makeover([](int){ std::cout << "int\n"; },
+[](double){ std::cout << "double\n"; });
o(42); // prints int
o(42.0); // prints double

auto o2 = makeover(+[]() noexcept {});
std::cout << noexcept(o2()); // prints 1
}

Demo

关于c++ - 使用经典重载解析规则创建依赖于 std::invoke 的重载集类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47986033/

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