gpt4 book ai didi

C++ 对可调用类型作为模板参数的约束

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:47:03 26 4
gpt4 key购买 nike

我正在尝试将以下 Scala 代码移植到 C++:

trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}

我试过类似的方法:

template<template <typename> class F>
struct Functor {
template <typename A, typename B>
static F<B> map(const F<A> &fa, ??? f); // What's the type of `f`?
};

但是我不知道如何表达f的类型(在 Scala 中是 A => BFunction1[A, B] )。使用 std::function使编译器无法进行有用的类型推断,也使使用 lambdas 变得尴尬(我需要显式指定模板参数,如

Functor<List>::map<Foo, Bar>(foos, [](const Foo &foo) -> Bar { return foo.toBar(); });

,否则编译器似乎无法推断出 B 是什么是)。解决方法似乎是:

template<template <typename> class F>
struct Functor {
template <typename A, typename A2B>
static auto map(const F<A> &fa, A2B f) -> F<decltype(f(fa[0]))>;
};

但这看起来很难看,而且F<A>可能并不总是支持括号运算符(或 ::value_type,就此而言)。有没有更好的方法来实现这个?

最佳答案

使用 std::result_of_t 和通用的 lambda 表达式,您将拥有足够好的调用代码:

template<template <typename> class F>
struct Functor {
template <typename A, typename A2B>
static auto map(const F<A> &fa, A2B f) -> F<std::result_of_t<A2B(A)>>;
};

auto bars = Functor<std::vector>::map(foos, [](const auto& foo) { return foo.toBar(); });

但是请注意,大多数标准 C++ 容器都有不止一个模板参数。使此代码与它们一起工作的最简单方法是将 Functor 的定义更改为

template<template <typename...> class F>
struct Functor {

并且您将无法为生成的容器类型指定其他模板参数,例如 Allocator,除非您为特定容器提供专门的专门化。

关于C++ 对可调用类型作为模板参数的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36414543/

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