Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何迭代(类外)作为向量的私有成员<;独特的_ptr<;T>&燃气轮机;_C++_C++11 - Fatal编程技术网

C++ 如何迭代(类外)作为向量的私有成员<;独特的_ptr<;T>&燃气轮机;

C++ 如何迭代(类外)作为向量的私有成员<;独特的_ptr<;T>&燃气轮机;,c++,c++11,C++,C++11,但是我不能使用getEmployees()函数返回employees\uu,因为unique\u ptr的向量是不可复制的 所以现在我有一个for_,each_,employee函数 for(auto const& e : getEmployees()) { e.get()->getName(); } 模板 无效组织::对于每个员工(可调用f){ 适用于(汽车施工与设备:员工){ f(e.get()); } } //我使用它就像, 每个员工的组织([](employee*e){

但是我不能使用
getEmployees()
函数返回
employees\uu
,因为unique\u ptr的向量是不可复制的

所以现在我有一个for_,each_,employee函数

for(auto const& e : getEmployees()) { e.get()->getName(); } 
模板
无效组织::对于每个员工(可调用f){
适用于(汽车施工与设备:员工){
f(e.get());
}
}
//我使用它就像,
每个员工的组织([](employee*e){e->getName();});
但我不喜欢这个想法,因为我必须为每个员工和每个项目写文章。我有类似结构的其他类似类。因此,我将为每个类型的函数编写大量的。这不是我想要的

我可以为这些类的朋友(比如包含唯一向量的组织)的每个函数设置泛型吗


如何(在类之外)迭代作为
向量的私有成员

最简单且可读性很强的方法是提供一个访问方法,该方法返回对数据成员的可能
常量
限定的引用。这样,您就不会试图复制不可复制的成员

template<class callable>
void Organization::for_each_employee(callable f) {
     for(auto const& e : employees_) {
        f(e.get());
   }
}

// And I use it like,
org.for_each_employee([](Employee* e){ e->getName(); });

最简单且可读性很强的方法是提供一个访问方法,该方法返回对数据成员的可能
const
限定的引用。这样,您就不会试图复制不可复制的成员

template<class callable>
void Organization::for_each_employee(callable f) {
     for(auto const& e : employees_) {
        f(e.get());
   }
}

// And I use it like,
org.for_each_employee([](Employee* e){ e->getName(); });

您可以在getEmployees()中返回employee_uu的引用以进行迭代

for (const auto& item : organizationInstance.getItems())
    item->doStuff();
const vector&getEmployees()
{
返回员工姓名;
}

您可以在getEmployees()中返回Employees_uu的引用以进行迭代

for (const auto& item : organizationInstance.getItems())
    item->doStuff();
const vector&getEmployees()
{
返回员工姓名;
}

您需要的是迭代器
std::vector::begin()
std::vector::end()
将迭代器返回到向量的第一个元素和结束元素之后的元素。然后你可以做类似的事情

const vector<unique_ptr<Employee>>& getEmployees()
{
    return employee_;
}
在哪里

const
版本返回
const
迭代器,迭代器类似于指向-
const
的指针,因为它们不允许修改向量。与返回对向量的引用相比,该方法的另一个好处是它将实现与接口完全解耦。如果出于任何原因你不在乎这个,你可以用这个来代替

class Organization {
    auto get_employees_begin() { return employees_.begin(); }
    auto get_employees_begin() const { return employees_.begin(); }

    auto get_employees_end() { return employees_.end(); }
    auto get_employees_end() const { return employees_.end(); }
}
这将允许您使用所有向量实用程序,但如果内部容器从向量更改为其他内容,也会使依赖它们的所有代码中断


在任何情况下,如果不应直接修改向量,您可能不希望提供非常量函数。

您需要的是迭代器
std::vector::begin()
std::vector::end()
将迭代器返回到向量的第一个元素和结束元素之后的元素。然后你可以做类似的事情

const vector<unique_ptr<Employee>>& getEmployees()
{
    return employee_;
}
在哪里

const
版本返回
const
迭代器,迭代器类似于指向-
const
的指针,因为它们不允许修改向量。与返回对向量的引用相比,该方法的另一个好处是它将实现与接口完全解耦。如果出于任何原因你不在乎这个,你可以用这个来代替

class Organization {
    auto get_employees_begin() { return employees_.begin(); }
    auto get_employees_begin() const { return employees_.begin(); }

    auto get_employees_end() { return employees_.end(); }
    auto get_employees_end() const { return employees_.end(); }
}
这将允许您使用所有向量实用程序,但如果内部容器从向量更改为其他内容,也会使依赖它们的所有代码中断


在任何情况下,如果不应直接修改向量,您可能不希望提供非
const
函数。

要仅允许迭代,而不提供任何其他特定于向量的操作,您可以使用
boost::range

class Organization {
    auto& get_employees() { return employees_; }
    const auto& get_employees() const { return employees_; }
}

要仅允许迭代,而不提供任何特定于向量的操作,您可以使用
boost::range

class Organization {
    auto& get_employees() { return employees_; }
    const auto& get_employees() const { return employees_; }
}

下面是一个简单的span类。它类似于gsl::span。它表示进入
T
元素(如数组中)的连续缓冲区的视图:

模板
结构跨度{
T*begin()常量{return b;}
T*end()常量{return e;}
T*data()常量{return begin();}
std::size_t size()常量{return end()-begin();}
bool empty()常量{return size()==0;}
span(T*s,T*f):b(s),e(f){}
span(T*s,std::size_T length):span(s,s+length){}
span()=默认值;
样板
跨度(标准::矢量和v):
跨度(v.data(),v.length())
{}
样板
跨度(标准::矢量常数和v):
跨度(v.data(),v.length())
{}
样板
跨度(T&arr)[N]:
跨度(arr,N)
{}
样板
范围(标准::阵列和阵列):
跨度(arr.data(),N)
{}
样板
范围(标准::数组常量和arr):
跨度(arr.data(),N)
{}
私人:
T*b=0;
T*e=0;
};
只需让您的
getEmployees
返回
span

这将公开调用者有效地迭代它所需的一切,而不再公开


更简单的替代方法是返回一个
std::vector const&
,但它泄漏了与
getEmployee
的使用者完全无关的实现细节。这里是一个简单的span类。它类似于gsl::span。它表示进入
T
元素(如数组中)的连续缓冲区的视图:

模板
结构跨度{
T*begin()常量{return b;}
T*end()常量{return e;}
T*data()常量{return begin();}
std::size_t size()常量{return end()-begin();}
bool empty()常量{return size()==0;}
span(T*s,T*f):b(s),e(f){}
span(T*s,std::size_T length):span(s,s+length){}
span()=默认值;
样板
跨度(标准::矢量和v):
跨度(v.data(),v.length())
{}
样板
跨度(标准::矢量常数和v):
跨度(v.data(),v.length())
{}
样板
跨度(T&arr)[N]:
跨度(arr,N)
{}
样板
范围(标准::阵列和阵列):
跨度(arr.data(),N)
{}
样板
范围(标准::数组常量和arr):
跨度(arr.data(),N)
{}
私人:
T*b=0;
T*e=0;
};