使用 c++20 概念传递参数化函数和参数列表
Pass parameterized function and list of parameters using c++20 Concepts
我有一个函数 foo
接受一个任意类型的参数,如下所示:
void foo(int& x)
{
x = 4;
}
现在我想创建一个模板函数 bar
,它接受一个带有 1 个参数的函数和一个参数列表来调用该函数。
template<typename Func, typename Params>
void bar(Func func, Params params)
{
for(auto param : params)
{
func(param);
}
}
这有效并编译,但我想改进它以使用 C++20 概念。首先,我创建了一个 iterable
概念,如下所示:
template<typename Container, typename ElementType>
concept iterable = std::ranges::range<Container> && std::same_as<typename std::iterator_traits<Container>::value_type, ElementType>;
并用它来检查迭代器的 value_type
是否与提供的容器的参数类型相同,如下所示:
template<typename Func, typename ParamType, typename Params>
requires std::invocable<Func, ParamType> && iterable<Params, ParamType>
void bar(Func func, Params params)
{
for(auto param : params)
{
func(param);
}
}
但是这个简单的例子无法编译
std::vector<int> payload(10, 5);
bar(&foo, payload);
出现以下错误信息
error C2672: 'bar': no matching overloaded function found
error C2783: 'void bar(Func,Params)': could not deduce template argument for 'ParamType'
这有点道理,因为 Func 和 Params 是函数的参数而 ParamType 不是,但我想解决这个问题而不必手动指定参数的类型。我还尝试将签名更改为 void bar(Func func, Params<ParamType> params)
或将模板更改为 ... typename ParamType, typename Params<ParamType>>
两者都没有编译。
如何在不显式指定 bar 的参数类型的情况下解决这个问题?
您可以使用标准库提供的工具来解决这个问题。您使用 input_range
和 invocable
概念,提供给定范围的 range_reference_t
类型作为调用函数的参数。
template<typename Func, std::ranges::input_range Rng>
requires std::invocable<Func, std::ranges::range_reference_t<Rng>>
void bar(Func func, Rng params)
{
for(auto &¶m : params)
{
std::invoke(func, param);
}
}
我有一个函数 foo
接受一个任意类型的参数,如下所示:
void foo(int& x)
{
x = 4;
}
现在我想创建一个模板函数 bar
,它接受一个带有 1 个参数的函数和一个参数列表来调用该函数。
template<typename Func, typename Params>
void bar(Func func, Params params)
{
for(auto param : params)
{
func(param);
}
}
这有效并编译,但我想改进它以使用 C++20 概念。首先,我创建了一个 iterable
概念,如下所示:
template<typename Container, typename ElementType>
concept iterable = std::ranges::range<Container> && std::same_as<typename std::iterator_traits<Container>::value_type, ElementType>;
并用它来检查迭代器的 value_type
是否与提供的容器的参数类型相同,如下所示:
template<typename Func, typename ParamType, typename Params>
requires std::invocable<Func, ParamType> && iterable<Params, ParamType>
void bar(Func func, Params params)
{
for(auto param : params)
{
func(param);
}
}
但是这个简单的例子无法编译
std::vector<int> payload(10, 5);
bar(&foo, payload);
出现以下错误信息
error C2672: 'bar': no matching overloaded function found
error C2783: 'void bar(Func,Params)': could not deduce template argument for 'ParamType'
这有点道理,因为 Func 和 Params 是函数的参数而 ParamType 不是,但我想解决这个问题而不必手动指定参数的类型。我还尝试将签名更改为 void bar(Func func, Params<ParamType> params)
或将模板更改为 ... typename ParamType, typename Params<ParamType>>
两者都没有编译。
如何在不显式指定 bar 的参数类型的情况下解决这个问题?
您可以使用标准库提供的工具来解决这个问题。您使用 input_range
和 invocable
概念,提供给定范围的 range_reference_t
类型作为调用函数的参数。
template<typename Func, std::ranges::input_range Rng>
requires std::invocable<Func, std::ranges::range_reference_t<Rng>>
void bar(Func func, Rng params)
{
for(auto &¶m : params)
{
std::invoke(func, param);
}
}