【发布时间】:2014-06-12 01:45:11
【问题描述】:
我正在尝试创建一个简单的模板enumerator 类,该类应该接受定义了: 运算符的任何对象,以及稍后在(i, v[i]) 形式的打印对上。一个简单的实现如下:
template<typename T>
struct enumerator {
T &v; // reference to minimize copying
enumerator(T &_v) : v(_v) {}
void do_enumerate() {
size_t i = 0;
for(auto x : v) {
cout << i << x << endl;
i++;
}
}
};
这适用于以下情况:
案例A
vector<int> v({1,2,6,2,4});
auto e = enumerator(v);
e.do_enumerate();
不过,我也希望它能够处理临时对象,例如:
案例 B
auto e = enumerator(vector<int>({2,3,9});
e.do_enumerate();
这不起作用,编译器抛出:
no matching function for call to ‘enumerator<std::vector<int> >::enumerator(std::vector<int>)
所以,我尝试添加一个
enumerator(T _t) : t(_T) {}
构造函数来解决这个错误。现在案例A不起作用,出现错误:
error: call of overloaded ‘enumerator(std::vector<int>&)’ is ambiguous
另外,情况B,枚举的输出不正确。
解决这个问题的最干净的方法是什么?我会
- 真的很喜欢这两种情况都可以工作
- 不希望使用 stdc++ 以外的任何库
- 希望尽可能少地复制(因此不能只在结构中存储
T t) - C++11 不是问题。我有 g++-4.8,我认为它有足够的 C++11 支持。
【问题讨论】:
-
您尝试过使用
T const&和T &&的构造函数吗?您确实意识到,一旦超出范围,右值就会被销毁。在enumerator类中保留对它的引用不会改变这一点。 -
没有
:operator这样的东西,这是基于范围的for语句的语法。它为begin()和end()创建迭代器,在后台对容器进行迭代。有关于 SO 处理它们如何工作的问题,搜索它们。 -
而您尝试做的事情没有意义。要么复制参数,要么不接受右值。
-
好吧,如果参数是右值,我想复制,如果不是,则不复制。这可能吗?
-
考虑到您的目标是避免不必要的复制,您可能应该使用
for (auto& x : v)而不是for (auto x : v)。