考虑 C 拥有一些资源且不可复制。
将多个 C 对象传递给某个方法的最佳方法是什么(hi_all
在我的问题的以下简化示例中)?
我找到的唯一解决方案是使用 std::reference_wrapper
。有没有更好的解决方案?
#include <iostream>
#include <vector>
#include <memory>
class C
{
public:
C(int i) throw() : i(i), isCopy(false) { }
//C(const C& c) = delete; //actual version
C(const C& c) throw() : i(c.i), isCopy(true) { }
C(C&& c) throw() : i(c.i), isCopy(c.isCopy) { }
void hi() const
{
std::cout<<"hi:\t"<<i<<", copy:\t"<<isCopy<<std::endl;
}
public:
int i;
bool isCopy;
};
void hi_all(const std::vector<C>& v)
{
std::cout<<"copies"<<std::endl;
for(auto &c : v)
c.hi();
}
void hi_all(const std::vector<std::reference_wrapper<C>>& v)
{
std::cout<<"ref wrappers"<<std::endl;
for(auto &c : v)
c.get().hi();
}
void hi_all(const std::vector<C>& v, std::function<bool (const C&)> predicate)
{
std::cout<<"predicate"<<std::endl;
for(auto &c : v)
{
if(predicate(c))
c.hi();
}
}
int main()
{
//one external source of objects
std::vector<C> v;
v.push_back(C(1));
v.push_back(C(2));
v.push_back(C(3));
//another source of objects. just one instance for simplicity
C another_c(4);
std::vector<C> v2;
std::vector<std::reference_wrapper<C>> v2_ref;
for(auto &c : v)
{
if(c.i > 1)
{
v2.push_back(c); //fail: copy ctor
v2_ref.push_back(std::reference_wrapper<C>(c));
}
}
v2.push_back(another_c); //fail: copy ctor
v2_ref.push_back(std::reference_wrapper<C>(another_c));
hi_all(v2);
hi_all(v2_ref);
hi_all(v, [](const C& c){ return c.i > 1; }); //fail: another_c lost.
return 0;
}
最佳答案
您使用 reference_wrapper
的解决方案对我来说似乎已经足够好了。请注意,您也可以使用指针 vector ,如果您对它们感觉更好(但我强烈坚持您的引用解决方案更清晰,因为它在逻辑上更正确).
如果您仍然想让它更简单/更好,我有两种方法。
首先,您可以将 v
和 another_C
作为单独的参数传递给函数。快速、简单,但可扩展性不强(可能您在这里不需要它?)。
其次,您可以创建一些通用包装器来生成引用 vector ,并在此代码中使用它们。
顺便说一句,如果您知道编译时的对象数量(不幸的是,情况似乎并非如此),您可以使用可变参数模板。
可以使用类似的方法来创建包装器:
template <typename T>
using refs_vector_t = std::vector<std::reference_wrapper<T>>;
template <typename T>
void refs_vector_impl (refs_vector_t<T> & result) { }
template <typename ... Ts>
void refs_vector_impl (refs_vector_t<T> & result, T const & x, Ts const & ... ts)
{
result.push_back(std::reference_wrapper<T>(x));
refs_vector_impl(result, ts...);
}
// assuming Con is a container of T
template <typename Con, typename ... Ts>
void refs_vector_impl (refs_vector_t<T> & result, Con const & con, Ts const & ... ts)
{
for (auto const & x : con)
refs_vector_impl(result, x);
refs_vector_impl(result, ts...);
}
template <typename T, typename ... Ts>
refs_vector_t<T> refs_vector (Ts const & ... ts)
{
refs_vector_t<T> result;
refs_vector_impl(result, ts...);
return result;
}
然后,在您的代码中的某处:
hi_all(refs_vector<C>(v, another_C));
关于c++ - 将多个对象传递给函数而不复制它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29418088/