【问题标题】:Use constructor as predicate使用构造函数作为谓词
【发布时间】:2015-02-23 07:00:38
【问题描述】:

我们可以使用构造函数作为谓词吗?到目前为止,我能够做到的是:

std::vector<const char*> v1 = {
    "Hello", "from", "GCC", __VERSION__, "!"
};
std::vector<std::string> v2(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(),
    [] (const char* s) { return std::string(s); });

但我想要一些方法来做std::tranform( ..., std::string)。我试过std::string::stringstd::string::basic_stringstd::string::basic_string&lt;char&gt;

【问题讨论】:

  • 你不能用构造函数做到这一点。为什么不只是vector&lt;string&gt; v2(v1.begin(), v1.end())
  • 我也没有看到在你的问题中使用std::transform 的意义,你真的有XY问题吗?
  • 我认为你的意思是函子不是谓词;谓词返回一个布尔值。
  • 这不是谓词。 predicate 是过滤条件。具体来说,它是一个接受一个参数并返回 bool 的函数。
  • @Deduplicator 也许这是哲学上的,但我认为真正的谓词(在 CS 中)需要返回一个布尔值,并且某些函数只是为您执行此转换。在 C++ 的上下文中,它们确实不需要是函数,也不需要返回 bool,此外,标准甚至知道所谓的“二元谓词”,我发现这是一个奇怪的扩展术语。

标签: c++


【解决方案1】:

做一个简单的

std::vector<std::string> v2;
v2.reserve(v1.size()); // Not really needed
for(auto x : v1) v2.emplace_back(x);

【讨论】:

  • 听说 range-for 循环不能给容器添加内容。
  • 他们可以。但是,如果您在容器上的 range-for-loop 中,您 1) 不知道当前元素具有哪个索引,并且 2) 不能使容器迭代器无效,因为 range-for 是基于迭代器的。
  • C++ 入门。可能我记性不太好。
  • @EmpereurAiman 这不是真的。正如 Deduplicator 所说,它们可以添加元素,但它们并非没有缺陷。
  • @Deduplicator 您可能希望将元素移入:v2.emplace_back(std::move(x))
【解决方案2】:

诀窍是我们需要将typename 传递给template,然后我们可以使用它来调用您想要的构造函数。

这是我想出的:

template<typename source, typename destination, typename iter, typename iter2>
void transform_object(iter begin, iter end, iter2 begin2)
{
    std::transform(begin, end, begin2, [](source s){ return destination(s); } );
}

并将其与您的原始代码一起使用:

transform_object<const char*, std::string>(v1.begin(), v1.end(), v2.begin());

【讨论】:

  • 为什么使用静态方法的结构?可以做成免费的函数模板,也可以用typename iter::value_type获取元素类型。
  • @0x499602D2 已修复。已经习惯了所有东西的结构......抓紧时间。
【解决方案3】:

我会这样做:

std::vector<std::string> v2(v1.begin(), v1.end());

【讨论】:

  • 最简单和最简单的,除非需要一些转换,否则应该首选它。在这种情况下,range-for 会获胜。
猜你喜欢
  • 2010-10-11
  • 2014-05-20
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多