std::函数模板参数解析
std::function template argument resolution
我目前正在开发一个库,链接函数对象。
我正在创建一个函数模板,它接受一个可调用对象(目前为std::function),并根据函数的输出和输入类型进行参数化。以下是我定义的一个简化版本:
template <typename In, typename Out>
std::vector<Out> process(std::vector<In> vals, std::function< Out(In) > func)
{
// apply func for each value in vals
return result;
}
我遇到的问题是使用问题。当我传递lambda时,编译器似乎无法正确推导类型,因此抱怨该函数不存在:
std::vector<string> strings;
// does NOT compile
auto chars = process(strings,
[]( std::string s ) -> char
{
return s[0]; // return first char
}
);
如果我显式地将lambda包装在std::function
中,程序将编译:
std::vector<string> strings;
// DOES compile
auto chars = process(strings,
std::function< char(std::string) >(
[]( std::string s ) -> char
{
return s[0]; // return first char
})
);
我还没有测试传递函数指针或函数对象,但如果我不直接传递显式std::function
对象,编译器似乎很难推导出In
和Out
参数。
我的问题是:有没有一种方法可以绕过这一点,这样我就可以推断出可调用对象的输入/返回类型,而无需在调用站点明确提及它们?
也许可以参数化函数类型上的模板,而不是输入/返回类型?本质上,我需要推导任意可调用函数的In
和Out
类型。对于模板函数的返回类型,可能有某种auto
/decltype
技巧?
谢谢。
我认为您可以创建一个中间返回类型推导函数,该函数使用decltype
来确定要传递给实际函数对象的参数:
template <typename Out, typename In>
std::vector<Out> process_intern(std::vector<In> vals, std::function< Out(In) > func)
{
// whatever
}
template <typename In, typename Func>
auto process(std::vector<In> vals, Func func) -> std::vector<decltype(func(vals[0]))>
{
return process_intern<decltype(func(vals[0]))>(vals, func);
}
当然,您可能需要考虑直接在process()
中实现逻辑,除非有理由键入擦除函数类型。
有没有办法绕过这一点,这样我就可以推断出可调用对象的输入/返回类型,而无需在调用站点明确提及它们?
否。模板参数推导中不考虑用户定义的转换。编译器必须想出In
和Out
,这样参数的类型和自变量的类型必须(几乎)完全匹配,但在这种情况下它们永远不会匹配。
也许在函数类型上参数化模板,而不是输入/返回类型
是的,这就是通常要做的(例如,看看标准库算法)
相关文章:
- std::span<const T> 作为函数模板中的参数
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- C++ std::functional 中的可变参数函数模板
- 概念解析为使用 std::make_signed_t 时意外的函数模板
- 请参阅在 Visual Studio 2019 中捕获 std::exception 时对函数模板实例化消息的引用
- 非模板 std::reference_wrapper赋值运算符和模板构造函数
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 可变参数模板函数:调用没有匹配函数,std::endl
- 将 std::type_index 作为模板参数传递给函数模板
- 构造函数模板参数推导,其中 std::function 作为参数
- 类模板的参数太少 "std::pair":在函数中将 std 对作为参数传递
- 为什么 std::函数模板构造函数不使用通用引用?
- 为什么重载分辨率不选择模板函数的 std::vector 重载?
- 错误 C2893 无法专门化函数模板'unknown-type std::invoke(_Callable &&,_Types &&...)'
- 无法专用化函数模板'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
- c 类构造函数模板,带有std :: enable_if和std :: decay
- 函数模板参数推断使用 std::Optional 失败
- 模板函数中 std::string 的类型推断失败
- 从 std 命名空间中专门化函数模板的想法有多糟糕?
- 有人能解释一下特殊的std::函数模板参数列表语法(这个奇怪的类型(Types..))吗