函数模板如何推断出 initializer_list 的嵌套次数?
How a function template can deduce the number of times an initializer_list is nested?
我有一个函数模板,它采用任意嵌套列表和 returns 数组:
#include <array>
#include <initializer_list>
template<size_t N, typename List>
std::array<size_t,N> some_function (const List& list)
{
// N is the number of times the list is nested.
std::array<size_t,N> arr;
return arr;
}
当我将此函数用于某些嵌套 std::initializer_list
时,如下所示:
int main () {
using List = std::initializer_list<std::initializer_list<double>>;
List list = {{1.,2.,3.},{4.,5.,6.}};
std::array<size_t,2> arr;
arr = some_function (list);
return 0;
}
我收到无法推导类型 N 的错误
couldn't deduce template parameter ‘N’
问题
- 如何改进我的函数模板来推断列表的嵌套次数?
- 对于这种情况,是否有比
std::initializer_list
更好的选择?
你可以写两个重载constexpr
function templates to calculate the nested times, with the help of std::enable_if
and SFINAE.
// types have not member type value_type
template <typename T, typename = void>
struct has_value_type: std::false_type {};
// types have member type value_type
template <typename T>
struct has_value_type<T, std::void_t<typename T::value_type>> : std::true_type {};
// return nested times as 0 for types without member type value_type
template<typename T>
constexpr std::enable_if_t<!has_value_type<T>::value, size_t> get_nested_times() {
return 0;
}
// return nested times as 1 plus times got on the nested type recursively
template<typename T>
constexpr std::enable_if_t<has_value_type<T>::value, size_t> get_nested_times() {
return 1 + get_nested_times<typename T::value_type>();
}
那么你可以在编译时得到嵌套时间
template<typename List>
auto some_function (const List& list)
{
// N is the number of times the list is nested.
constexpr auto N = get_nested_times<List>();
std::array<size_t, N> arr;
return arr;
}
我有一个函数模板,它采用任意嵌套列表和 returns 数组:
#include <array>
#include <initializer_list>
template<size_t N, typename List>
std::array<size_t,N> some_function (const List& list)
{
// N is the number of times the list is nested.
std::array<size_t,N> arr;
return arr;
}
当我将此函数用于某些嵌套 std::initializer_list
时,如下所示:
int main () {
using List = std::initializer_list<std::initializer_list<double>>;
List list = {{1.,2.,3.},{4.,5.,6.}};
std::array<size_t,2> arr;
arr = some_function (list);
return 0;
}
我收到无法推导类型 N 的错误
couldn't deduce template parameter ‘N’
问题
- 如何改进我的函数模板来推断列表的嵌套次数?
- 对于这种情况,是否有比
std::initializer_list
更好的选择?
你可以写两个重载constexpr
function templates to calculate the nested times, with the help of std::enable_if
and SFINAE.
// types have not member type value_type
template <typename T, typename = void>
struct has_value_type: std::false_type {};
// types have member type value_type
template <typename T>
struct has_value_type<T, std::void_t<typename T::value_type>> : std::true_type {};
// return nested times as 0 for types without member type value_type
template<typename T>
constexpr std::enable_if_t<!has_value_type<T>::value, size_t> get_nested_times() {
return 0;
}
// return nested times as 1 plus times got on the nested type recursively
template<typename T>
constexpr std::enable_if_t<has_value_type<T>::value, size_t> get_nested_times() {
return 1 + get_nested_times<typename T::value_type>();
}
那么你可以在编译时得到嵌套时间
template<typename List>
auto some_function (const List& list)
{
// N is the number of times the list is nested.
constexpr auto N = get_nested_times<List>();
std::array<size_t, N> arr;
return arr;
}