我可以在这里使用模板特化或类型强制转换吗?
Can I use template specialization or type coercion here?
我有一个用于将慢函数映射到集合的现有模板(以同名clojure函数的风格),我想在这篇有用的博客文章中使用"move semantics"来加速:http://blog.knatten.org/2012/11/02/efficient-pure-functional-programming-in-c-using-move-semantics/
我写的旧代码对我来说很好:
template <typename function,
template <typename...> class collection,
typename in_type,
typename... types,
typename out_type =
typename std::result_of<function(in_type)>::type>
static collection<out_type> pmap(
const function& f, const collection<in_type, types...>& c) {
collection<out_type> result;
if(!c.empty()) {
result = collection<out_type>(c.size());
__gnu_parallel::transform(c.cbegin(),c.cend(),result.begin(),f);
}
return result;
}
既然我愿意放弃输入集合,那么在in_type与out_type相同的情况下,我应该能够通过在c上编写而不是分配整个新集合来加速这一点。我尝试过模板专门化,但编译器无法在特殊情况下进行选择,我也无法修复。下面是我尝试的一些技巧:
template <typename function,
template <typename...> class collection,
typename in_type,
typename... types,
typename out_type =
typename std::result_of<function(in_type)>::type>
static collection<out_type> pmap(
const function& f, const collection<in_type, types...>&& c) {
collection<out_type> result;
if(!c.empty()) {
if(typeid(in_type)==typeid(out_type)) {
__gnu_parallel::transform(c.begin(),c.end(),c.begin(),f);
result = c;
}
else {
result = collection<out_type>(c.size());
__gnu_parallel::transform(c.cbegin(),c.cend(),result.begin(),f);
}
}
return std::move(result);
}
我猜有一些hack会让编译器接受result=c(即使它不应该关心,因为周围的if语句),但像这样的类型转换让我感到不安。对于如何解决这个问题或为重写情况添加专门化模板有什么建议吗?
typeid
是一个运行时结构,所以你试图在运行时而不是编译时选择行为。
您可以编写两个重载并使用std::enable_if
选择正确的重载:
template <typename function,
template <typename...> class collection,
typename in_type,
typename... types,
typename out_type =
typename std::result_of<function(in_type)>::type,
typename std::enable_if<!std::is_same<in_type, out_type>::value>::type* = nullptr>
static collection<out_type> pmap(
const function& f, collection<in_type, types...>&& c) {
collection<out_type> result;
result.reserve(c.size());
__gnu_parallel::transform(c.cbegin(),c.cend(),std::back_inserter(result),f);
return result;
}
template <typename function,
template <typename...> class collection,
typename in_type,
typename... types,
typename out_type =
typename std::result_of<function(in_type)>::type,
typename std::enable_if<std::is_same<in_type, out_type>::value>::type* = nullptr>
static collection<out_type,types...> pmap(
const function& f, collection<in_type, types...>&& c) {
__gnu_parallel::transform(c.begin(),c.end(),c.begin(),f);
return std::move(c);
}
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++中的双指针类型转换
- 逐位操作的隐式类型转换
- 模板中的类型转换
- 在 C++(和 C)中进行类型转换时明显不一致
- 字符类型转换不兼容
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- C++:用户定义的显式类型转换函数错误
- 将类指针类型转换为键时出错
- 通过引用传递参数时C++类型转换
- 在 C++ 中将一个模板类型的对象类型转换为另一个模板类型
- C++显式类型转换(C 样式强制转换)的强制表示法和static_cast的多种解释
- C++无效的函数类型转换
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 如何将Windows产品类型转换为名称?
- 通过构造函数方法输出的类到类类型转换是 5500 为什么不是 5555
- 事件系统:使用类型转换或联合进行继承
- 如何在参数中定义隐式类型转换的构造函数?
- 类模板实例化中的类型转换