gpt4 book ai didi

c++ - 如何在模板中存储右值或左值引用

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:10:45 26 4
gpt4 key购买 nike

我正在尝试创建一个简单的模板 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 支持。

最佳答案

Well I would like to copy in case the argument is an rvalue, and not copy in case it is not. Is that possible?

这可以使用 make_enumerator 来完成辅助函数,如图所示。

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();
}

这是如何运作的?

如果 make_enumerator 的参数是 A 类型的左值然后 T推导为 A&我们得到枚举器 enumerator<A&> ,而如果它是 A 类型的右值然后 T推导为 A我们得到枚举器 enumerator<A> .

在第一种情况下,成员 enumerator::v将具有类型 A& ,绑定(bind)到构造函数参数的左值引用(无复制)。在第二种情况下,成员将具有类型 A . std::forward的使用转换参数 _v为右值,因此它将在用于初始化 v 时被移动.

关于c++ - 如何在模板中存储右值或左值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24175279/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com