C++ 如何在模板中存储右值或左值引用
我正在尝试创建一个简单的模板C++ 如何在模板中存储右值或左值引用,c++,c++11,rvalue,C++,C++11,Rvalue,我正在尝试创建一个简单的模板枚举器类,该类应接受定义了:运算符的任何对象,然后打印(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;
枚举器
类,该类应接受定义了:
运算符的任何对象,然后打印(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不起作用,出现错误:
error: call of overloaded ‘enumerator(std::vector<int>&)’ is ambiguous
错误:重载的“枚举器(std::vector&)”的调用不明确
此外,在案例B中,枚举的输出不正确
解决这个问题最干净的方法是什么?我会的
- 我真的希望这两种情况都能奏效
- 不希望使用stdc以外的任何库++
- 需要尽可能少的复制(因此在结构中只存储
不是一个选项)T
- C++11不是问题。我有g++-4.8,我认为它有足够的C++11支持
类
/结构
(它实际上引入了无用的代码),只需使用好的旧函数即可:
template<typename Container>
void enumerate(const Container& t) {
std::size_t i = 0;
for(auto it = t.begin(); it != t.end(); ++it, ++i)
std::cout << i << *it << std::endl;
}
模板
无效枚举(常量容器和t){
标准:尺寸i=0;
for(auto it=t.begin();it!=t.end();++it,++i)
标准::cout
如果参数是右值,我想复制,如果不是,我不想复制。这可能吗
如图所示,这可以通过使用make_枚举器
helper函数来实现
template <class T>
struct enumerator {
T v;
enumerator(T&& _v) : v(std::forward<T>(_v)) {}
void do_enumerate() {
size_t i = 0;
for(auto x : v) {
cout << i << x << endl;
i++;
}
}
};
template <class T>
enumerator<T> make_enumerator(T&& x) {
return enumerator<T>(std::forward<T>(x));
}
int main() {
vector<int> v {5, 2, 9, 1};
make_enumerator(v).do_enumerate();
make_enumerator(std::move(v)).do_enumerate();
}
模板
结构枚举器{
电视
枚举数(T&&&u v):v(std::forward(_v)){
void do_enumerate(){
尺寸i=0;
用于(自动x:v){
您是否尝试过使用T const&
和T&
的构造函数?您确实意识到,一旦右值超出范围,它就会被销毁。在枚举器
类中保留对它的引用不会改变这一点。没有操作符
这类东西,这是基于范围的st的语法它为begin()
和end()创建迭代器
幕后是对容器的迭代。关于如何处理它们的工作,有一些问题,请搜索它们。您试图做的是没有意义的。要么复制参数,要么不接受右值。如果参数是右值,我想复制,如果不是,我不想复制。这可能吗?Considering您的目标是避免不必要的复制,您可能应该使用for(auto&x:v)
而不是for(auto x:v)
。谢谢。这很有效。但是,拥有一个对象会很好,因为我计划为枚举器
类本身定义一个迭代器接口。这样我就可以为(auto p:enumerate(whatever)){}
@subasisda是正确的,这非常有用,因为vector
本身不支持这一点……哦wait@SubhasisDas如果您正在计划创建一个像Strut这样的范围,请考虑使用(或者至少从中吸取灵感)。。我知道boost可能具有我想要的所有功能。但是,我想让自己了解C++11中的新功能,因此这更像是一项教育工作。我将研究boost.range api。@0x499602D2如果T
是左值引用,那么T&
是同一类型(不是右值引用)。此外,我已经尝试过此代码。好的,我现在明白了。谢谢。很酷。这适用于所有场景。我将尝试理解std::forward
更多信息。:)
enumerator(T _t) : t(_T) {}
error: call of overloaded ‘enumerator(std::vector<int>&)’ is ambiguous
template<typename Container>
void enumerate(const Container& t) {
std::size_t i = 0;
for(auto it = t.begin(); it != t.end(); ++it, ++i)
std::cout << i << *it << std::endl;
}
enumerate(std::vector<int>{2,3,9});
template <class T>
struct enumerator {
T v;
enumerator(T&& _v) : v(std::forward<T>(_v)) {}
void do_enumerate() {
size_t i = 0;
for(auto x : v) {
cout << i << x << endl;
i++;
}
}
};
template <class T>
enumerator<T> make_enumerator(T&& x) {
return enumerator<T>(std::forward<T>(x));
}
int main() {
vector<int> v {5, 2, 9, 1};
make_enumerator(v).do_enumerate();
make_enumerator(std::move(v)).do_enumerate();
}