gpt4 book ai didi

c++ - 专注于默认模板参数包

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

假设我已经为 STL 元组(元组、对)以及 STL 序列( vector 、列表、双端队列)编写了通用映射函数。现在我想编写一个全局映射函数,在给定输入类型的情况下调用适当的特殊函数。

我有一些类似的东西

template <typename... Ts>
struct mappable {
static constexpr bool is_instance = false;
};

template <typename... Tuples, typename = require<all<is_stl_tuple, Tuples...>::value>>
struct mappable<Tuples...> {
template <typename Func>
auto map(Func&& f, Tuples&&... ts) {
return tuple::map(std::forward<Func>(f), ts...);
}

static constexpr bool is_instance = true;
};

template <typename... Sequences, typename = require<all<is_stl_sequence, Sequences...>::value>>
struct mappable<Sequences...> {
template <typename Func>
auto map(Func&& f, Sequences&&... seqs) {
return sequence::map(std::forward<Func>(f), seqs...);
}

static constexpr bool is_instance = true;
};

template <typename Func, typename... Ts>
auto map(Func&& f, Ts&&... ts) {
static_assert(mappable<Ts...>::is_instance, "Tried calling map on unsupported types. Mappable arguments must be supplied.");
return mappable<Ts...>::map(std::forward<Func>(f), std::forward<Ts>(ts)...);
}

尽管希望类型检查函数 defs 不言自明:

// true iff Unary<Ts>::value... == true for at least one Ts
template <template <typename> class Unary, typename... Ts>
struct any;

// true iff Unary<Ts>::value... == true for all Ts
template <template <typename> class Unary, typename... Ts>
struct all;

template <bool B>
using require = typename std::enable_if<B>::type;

显然,这不会(也不会)起作用,因为我将 mappable 专门用于默认参数。有什么方法可以做到这一点,如果没有(我必须重新设计),您将如何重新设计这些功能? sequence::map 应采用 STL 序列的任意组合,因此我对重组的所有想法只是将问题转移到别处......

在此先感谢您的帮助...

编辑:根据要求,这里是使用示例(实际上是我的测试代码)我开始执行上述操作之前:

auto t0 = std::make_tuple(2.f, -5, 1);
auto t1 = std::make_tuple(1, 2);
auto b0 = tuple::map([] (auto v) { return v > decltype(v)(0); }, t0);
auto r0 = tuple::map([] (auto v0, auto v1) { return v0 + v1; }, t0, t1);
// b0 is tuple<bool, bool, bool>(true, false, true)
// b1 is tuple<float, int>(3.f, -3)

对于序列:

std::vector<float> s0 = {1.f, 2.f, 3.f, 0.f};
std::list<int> s1 = {3, 0, -2};
auto r = sq::map([] (auto v0, auto v1) { return v0 + v1; }, s0, s1);
// type of r is compound type of first argument (vector here), result is
// vector<float>(4.f, 2.f, 1.f)

这些 map 函数的实现是完全不同的 - 我上面的方法的目的是能够删除 namespace 并只使用 map 让它做正确的事情。

最佳答案

为什么不只是两个函数重载?

template <typename Func, typename... Tuples,
require<all<is_stl_tuple, Tuples...>>...>
auto map(Func&& f, Tuples&&... ts) {
return tuple::map(std::forward<Func>(f), std::forward<Tuples>(ts)...);
}

template <typename Func, typename... Sequences,
require<all<is_stl_sequence, Sequences...>>...>
auto map(Func&& f, Sequences&&... seqs) {
return sequence::map(std::forward<Func>(f), std::forward<Sequences>(seqs)...);
}

它对 require 进行了调整,以便两个重载能够很好地发挥作用:

template <bool condition>
struct require_impl {};

template <>
struct require_impl<true> {
enum class type {};
};

template <typename Condition>
using require = typename require_impl<Condition::value>::type;

关于c++ - 专注于默认模板参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21218475/

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