假设我有这个:
items
现在,在重构期间,我可能会在sorted_items
中拥有内容,或者我可能会在HoldStuff holder; // assume it was filled earlier
auto iter = holder.items.empty() ? holder.sorted_items.begin() :
holder.items.begin();
auto iter_end = holder.items.empty() ? holder.sorted_items.end() :
holder.items.end();
for (; iter != iter_end; ++iter) {
auto& item = *iter;
// Do stuff
}
中拥有内容,但无论我想对每个项目执行相同的操作。我想做这样的事情:
justin bieber -sucks
当我去编译它时,我得到错误抱怨不兼容的操作数类型。当然这是可能的,不是吗?
答案 0 :(得分:1)
您有两种选择:
any_range
或any_iterator
)do_stuff
委托给采用任何迭代器的函数模板以下是代码示例:
#include <vector>
#include <set>
#include <iostream>
#include <boost/range/any_range.hpp>
template<typename Iterator>
void do_stuff(Iterator begin, Iterator end) {}
int main()
{
std::vector<int> items;
std::set<int> sorted_items;
// first option
typedef boost::any_range<int, boost::forward_traversal_tag, int&, std::ptrdiff_t> my_any_range;
my_any_range r;
if(items.empty())
r = my_any_range(sorted_items);
else
r = my_any_range(items);
for (auto& x : r) {
std::cout << x << " ";
}
// second option
// this could also be a lambda and std::for_each
if(items.empty())
do_stuff(sorted_items.begin(), sorted_items.end());
else
do_stuff(items.begin(), items.end());
return 0;
}
答案 1 :(得分:0)
错误是正确的: auto 关键字在编译期间有效。简单来说,它只是推断出分配的类型并使用这种真实类型。但是决定它的矢量迭代器还是设置是在运行时制作的。所以类型无法推断。 正如SergeyA所说,我在这里错了,编译器失败了?:运算符,在auto之前。但原因仍然相同 - 它不知道使用哪种类型的结果。
您应该使用一些更通用的迭代器类型+多态,或者您可以在类型上对此函数进行参数化,其中T是迭代器类型。我更愿意这样做:
template<class T> do_stuff(T &c) { for (auto &el : c) { /*Whatever*/ } }
...
if (!items.empty()) {
do_stuff(items);
} else if (!sorted_items.empty()) {
do_stuff(sorted_items);
}
P.S。:这是一个概念,我没有测试代码。
答案 2 :(得分:0)
三元运算符的两侧需要具有相同的类型。在你的情况下,它们是不同的 - std :: vector&lt;&gt; :: iterator和std :: set&lt;&gt;迭代器。一个合适的解决方案似乎是某种迭代器包装器,它根据初始条件返回一个或另一个。
答案 3 :(得分:0)
auto
表示编译器将在编译时推断出后面的类型。
在这种情况下,三元条件运算符的返回类型是在问号后面,因此它是std::set<StuffItem, StuffItemComparator>::iterator
并且编译器尝试将列(std::vector<StuffItem>::iterator
)之后的内容转换为此不兼容类型因此编译错误。
您可以做的是让您的商品处理代码通用,如下所示:
auto doStuff = [] (StuffItem& item) {
// do stuff with item...
};
if( holder.items.size() )
for_each( holder.items.begin(), holder.items.end(), doStuff );
else if( holder.sorted_items.size() )
for_each( holder.sorted_items.begin(), holder.sorted_items.end(), doStuff );