C :模板参数扣除传递模板作为参数函数到其他模板函数
C++: Template argument deduction when passing template functions as argument to other template functions
我有以下示例代码的片段:
这个想法是有一个容器类,这里称为Box
,我们可能希望通过在其当前内容上映射功能来创建此容器的新版本。
#include <iostream>
#include <tuple>
template <typename TContent>
class Box
{
TContent d_content;
public:
Box(TContent content)
:
d_content(content)
{}
TContent content() const
{
return d_content;
}
template <typename Function>
auto transform(Function fun) -> decltype(Box{fun(d_content)})
{
return Box{fun(d_content)};
};
};
template <typename TElem>
std::tuple<TElem, TElem> toTuple(TElem thing)
{
std::cout << "Transforming " << thing << "to tuple.n";
return std::make_tuple(thing, thing);
}
int main() {
std::cout << "Hello World!n";
Box<int> mybox{10};
Box<int> box2 = mybox.transform([](int content){ return content * 2;});
std::cout << "Transformed box: " << box2.content() << 'n';
Box<std::tuple<int, int>> box3 = mybox.transform(&toTuple); // <- Template argument deduction/substitution fails here!
std::cout << "Transformed box: " << std::get<0>(box3.content()) << 'n';
}
在这里尝试
在创建Box3的第42行,模板参数扣除/替换失败:
main.cpp: In function 'int main()':
main.cpp:42:60: error: no matching function for call to 'Box<int>::transform(<unresolved overloaded function type>)'
Box<std::tuple<int, int>> box3 = mybox.transform(&toTuple);
^
main.cpp:22:8: note: candidate: template<class Function> decltype (Box<TContent>{fun(((Box<TContent>*)this)->Box<TContent>::d_content)}) Box<TContent>::transform(Function) [with Function = Function; TContent = int]
auto transform(Function fun) -> decltype(Box{fun(d_content)})
^~~~~~~~~
main.cpp:22:8: note: template argument deduction/substitution failed:
main.cpp:42:60: note: couldn't deduce template parameter 'Function'
Box<std::tuple<int, int>> box3 = mybox.transform(&toTuple);
^
exit status 1
尝试将模板函数(函数模板?)传递到一个函数时,似乎是这种情况。
避免这种情况的唯一方法是将所有模板函数包装在lambdas或其他非模板函数中。这当然是次优的,因为它引入了许多样板。
为什么在这种情况下为模板参数扣除失败,并且有一种方法可以更改Box
类(和/或其transform
成员函数)的代码以确保模板参数扣除em>工作?
(给定代码为c 11作为repl。它尚未支持C 14。C 14中的主要区别是可以省略transform
的落后返回类型。但是,错误仍然相同。我对(仅)在C 14中起作用的解决方案感到满意。)
在您的示例中:
template <typename Function>
auto transform(Function fun) -> decltype(Box{fun(d_content)})
Box
是类模板,而不是类。在课堂内,Box
是注入式class-name ,它始终是指Box<TContent>
。因此,如果您需要更改 type (因为transform
很可能需要这样做),这将行不通。您需要根据 Function
是要指定 Box
:
template <class Function,
class U = std::result_of_t<Function&(TContent)>>
Box<U> transform(Function fun)
{
return Box<U>{fun(d_content)}; // or even better, Box<U>{std::invoke(fun, d_content)}
};
第二个问题是您调用它:
Box<std::tuple<int, int>> box3 = mybox.transform(&toTuple);
toTuple
是函数模板,而不是函数。您无法将其传递给另一个功能模板,因为它没有类型,因此无法推导。和以前一样,您需要指定要您想要的 toTuple
:
Box<std::tuple<int, int>> box3 = mybox.transform(toTuple<int>);
或将整个内容包裹在lambda中(这是一个简化的实现,不关心副本,参考或sfinae):
Box<std::tuple<int, int>> box3 = mybox.transform([](auto x) { return toTuple(x); });
相关文章:
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 当从函数参数中的临时值调用复制构造函数时
- 如何从"decltype()"获取函数参数的数量<funtion>?
- 如何将lambda作为模板类的成员函数参数
- 模板参数推导失败,函数参数/参数不匹配
- 如何在C++中将迭代器作为函数参数传递
- 将函数参数"const char*"转换为"std::string_view"是
- C++ 如何将数组值解压缩为函数参数
- 主函数参数的属性
- 具有两个间接寻址运算符 (C++) 的函数参数的用途
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 如何定义在用作函数参数时工作的类模板的转换
- 将函数参数完美转发到函数指针:按值传递呢?
- 为什么我不能将引用作为 std::async 的函数参数传递
- 什么..(省略号)作为函数原型中唯一的函数参数,C++?
- 是否可以就地构造一个固定大小的数组作为函数参数?
- 接受模板作为函数参数
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- Arduino 函数参数