gpt4 book ai didi

templates - 如何查找具有默认值的可变数量 constexpr std::arrays 的 constexpr max

转载 作者:行者123 更新时间:2023-12-02 23:16:33 25 4
gpt4 key购买 nike

所以,我有一些constexpr std::array<int, N>对于 N 的各种值。在这种情况下:

constexpr std::array<int, 3> r1 {1, 3, 5};
constexpr std::array<int, 2> r2 {3, 4};
constexpr std::array<int, 4> r3 {1, 2, 5, 6};
constexpr std::array<int, 2> r4 {2, 6};

我想做的是找到constexpr max (以及随后的 min )元素跨越所有 array s。这似乎工作得很好:

constexpr int the_max() {
return 0;
}

template<typename T, typename... Ts>
constexpr int the_max(T&& t, Ts&&... ts) {
const int v = *std::max_element(t.cbegin(), t.cend());
return std::max(v, the_max(ts...));
}

如下所示:

constexpr auto max_entry = dlx::the_max(r1, r2, r3);
std::cout << max_entry << '\n';

如预期的那样打印 6。

不过,感觉这里应该多一些逻辑,比如:

  1. 默认(或最小)值;和

  2. std::array 中的类型应该可以不同,只要它们都是算术类型。

我觉得这应该可行:

template<typename B>
constexpr std::enable_if_t<std::is_arithmetic_v<B>, B>
the_max2(B&& b) {
return b;
}

template<typename B, typename T, typename... Ts>
constexpr std::enable_if_t<std::is_arithmetic_v<B> && std::is_arithmetic_v<T::value_type>, std::common_type_t<B, typename T::value_type>>
the_max2(B&& b, T&& t, Ts&&... ts) {
const int v = *std::max_element(t.cbegin(), t.cend());
return std::max(v, the_max2(ts...));
}

但结果是:

error: no matching function for call to 'the_max2<int>(int, const std::array<int, 3>&, const std::array<int, 2>&, const std::array<int, 4>&)'

只期望 1 个参数,但收到 4 个参数,并且:

 error: 'value_type' is not a member of 'const std::array<int, 3>&'

有人告诉我我做错了什么吗?任何帮助将不胜感激。

最佳答案

一些问题,排名不分先后

(1) 正如 S.M. 所指出的,您忘记了 T::value_type 之前的 typename

template<typename B, typename T, typename... Ts> // .......................VVVVVVVV
constexpr std::enable_if_t<std::is_arithmetic_v<B> && std::is_arithmetic_v<typename T::value_type>, std::common_type_t<B, typename T::value_type>>

(2) 你在递归调用中忘记了b

// .........................V
return std::max(v, the_max2(b, ts...));

(3) 当您应该使用 auto (或 typename T::value_type,如果你愿意的话)

// ...VVVV (not int)
const auto v = *std::max_element(t.cbegin(), t.cend());

(4) “通用类型”也应该评估 Ts::value_type,因此

// ...........................................VVVVVVVVVVVVVVVVVVVVVVVVVV
std::common_type_t<B, typename T::value_type, typename Ts::value_type...>

(5) 您应该明确 std::max() 的类型。

   using rt = std::common_type_t<B, typename T::value_type, typename Ts::value_type...>;
// ...
return std::max<rt>(v, the_max2(b, ts...));
// ............^^^^

(6) 我建议接收参数作为 const 指针而不是右值

 //..........VVVVVVV......VVVVVVV.......VVVVVVV
the_max2 (B const & b, T const & t, Ts const & ... ts)

以下是一个完整的编译示例(经过简化,仅检测一次返回的常见类型)

#include <array>
#include <iostream>
#include <algorithm>
#include <type_traits>

template <typename B>
constexpr std::enable_if_t<std::is_arithmetic<B>::value, B>
the_max2 (B const & b)
{ return b; }


template <typename B, typename T, typename ... Ts,
typename RT = std::common_type_t<B, typename T::value_type,
typename Ts::value_type...>>
constexpr std::enable_if_t<std::is_arithmetic<B>::value
&& std::is_arithmetic<typename T::value_type>::value, RT>
the_max2 (B const & b, T const & t, Ts const & ... ts)
{
const auto v = *std::max_element(t.cbegin(), t.cend());
return std::max<RT>(v, the_max2(b, ts...));
}

int main()
{
constexpr std::array<short, 3> r1 {{1, 3, 5}};
constexpr std::array<int, 2> r2 {{3, 4}};
constexpr std::array<long, 4> r3 {{1, 2, 5, 6}};
constexpr std::array<long long, 2> r4 {{2, 6}};

auto m { the_max2(4l, r1, r2, r3, r4) };

std::cout << m << std::endl;
}

额外建议:如果您可以放弃 std::is_arithmetic 测试,则不需要递归,您可以编写您的函数,只需扩展可变参数模板,如下所示

template <typename B, typename ... Ts,
typename RT = std::common_type_t<B, typename Ts::value_type...>>
constexpr RT the_max3 (B const & b, Ts const & ... ts)
{ return std::max<RT>({b, *std::max_element(ts.cbegin(), ts.cend())...}); }

如果您可以使用 C++17,而不是 C++14,则可以使用模板折叠来恢复 std::is_arithmetic SFINAE 测试,如下所示

template <typename B, typename ... Ts,
typename RT = std::common_type_t<B, typename Ts::value_type...>>
constexpr std::enable_if_t<
(std::is_arithmetic<B>::value && ...
&& std::is_arithmetic<typename Ts::value_type>::value), RT>
the_max3 (B const & b, Ts const & ... ts)
{ return std::max<RT>({b, *std::max_element(ts.cbegin(), ts.cend())...}); }

关于templates - 如何查找具有默认值的可变数量 constexpr std::arrays 的 constexpr max,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53037785/

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