[英]template inheritance C++ iterator
template<class T, template<typename> class Seq>
class SequenceWithApply : public Seq<T*>
{
public:
// 0 arguments, any type of return value:
template<class R>
void apply(R (T::*f)()) {
iterator it = begin();
while(it != end()) {
((*it)->*f)();
it++; }
}
// 1 argument, any type of return value:
template<class R, class A>
void apply(R(T::*f)(A), A a) {
iterator it = begin();
while(it != end()) {
((*it)->*f)(a);
it++; }
}
// 2 arguments, any type of return value:
template<class R, class A1, class A2>
void apply(R(T::*f)(A1, A2),
A1 a1, A2 a2) {
iterator it = begin();
while(it != end()) {
((*it)->*f)(a1, a2);
it++;
}
}
}; ///:~
//: C03:applyGromit2.cpp
// Test applyMember.h
#include "Gromit.h"
#include "applyMember.h"
#include <vector>
#include <iostream>
using namespace std;
int main() {
SequenceWithApply<Gromit, vector> dogs;
for(int i = 0; i < 5; i++)
dogs.push_back(new Gromit(i));
dogs.apply(&Gromit::speak, 1);
dogs.apply(&Gromit::eat, 2.0f);
dogs.apply(&Gromit::sleep, 'z', 3.0);
dogs.apply(&Gromit::sit);
} ///:~
I did not quite understand why compiler complain about iterator
here. 我不太明白为什么编译
iterator
在这里抱怨iterator
。 Since this snippet code implemente a class SequenceWithApply
based on the template. 由于此代码段代码基于模板实现了一个
SequenceWithApply
类。 In this case, SequenceWithApply
is actually a based class of vector
. 在这种情况下,
SequenceWithApply
实际上是vector
的基类。 iterator should be visible in this base class. 迭代器应该在此基类中可见。 I really appreciate that someone can help me figure this out.
我真的很感谢有人可以帮助我解决这个问题。
The compiler looks for iterator
on first-phase lookup, which is before the template is ever instantiated. 编译
iterator
在第一阶段查找时寻找iterator
,这是在模板实例化之前进行的。 In order to know from which type the class derives, the template must be instantiated (so that Seq<T*>
is an actual type). 为了知道该类是从哪种类型派生的,必须实例化该模板(以便
Seq<T*>
是实际类型)。 Thus, the compiler never finds iterator
in the base class yet. 因此,编译器从未在基类中找到
iterator
。
You can get around this in two easy ways: 您可以通过两种简单的方法解决此问题:
A one-off: 一次性:
typename Seq<T*>::iterator
A type alias in your derived class: 派生类中的类型别名:
using iterator = typename Seq<T*>::iterator;
All of these unambiguously specify to which type iterator
belongs, looked up in the second phase of lookup when Seq
and T
are known. 所有这些明确指定了
iterator
所属的类型,并在知道Seq
和T
的第二个查找阶段中对其进行查找。 More on typename
. 有关
typename
更多信息 。
You can do the same for your functions: 您可以对功能执行相同的操作:
A one-off: 一次性:
Seq<T*>::begin()
this->begin() // if inside a member function
A using declaration: 使用声明:
using Seq<T*>::begin;
The book you're using may be out of date. 您正在使用的书可能已过时。 These days c++ has moved in the direction of using free functions for better decoupling.
如今,c ++已朝着使用自由函数实现更好的去耦的方向发展。
Example: 例:
#include <vector>
#include <iostream>
// an example Gromit
struct Gromit
{
Gromit(int index) : index(index) {};
void speak(int i) { std::cout << name() << " speaking " << i << std::endl; }
void eat(float f) { std::cout << name() << " eating " << f << std::endl; }
void sleep(char c, double f) { std::cout << name() << " sleeping " << c << " " << f << std::endl; }
void sit() { std::cout << name() << " sitting" << std::endl; }
private:
std::string name() const {
return "Gromit " + std::to_string(index);
}
int index;
};
// apply some function object to each item in a container
template<class Container, class F>
void apply(Container& container, F f)
{
for (const auto& p : container)
{
f(p);
}
}
int main() {
std::vector<std::unique_ptr<Gromit>> dogs;
for(int i = 0; i < 5; i++)
dogs.emplace_back(new Gromit(i));
using namespace std::placeholders;
// apply dog.speak(1) to each dog in dogs...
apply(dogs, std::bind(&Gromit::speak, _1, 1));
// dog.eat(2.0f) for each dog in dogs...
apply(dogs, std::bind(&Gromit::eat, _1, 2.0f));
// ...etc
apply(dogs, std::bind(&Gromit::sleep, _1, 'z', 3.0));
apply(dogs, std::bind(&Gromit::sit, _1));
}
expected output: 预期输出:
Gromit 0 speaking 1
Gromit 1 speaking 1
Gromit 2 speaking 1
Gromit 3 speaking 1
Gromit 4 speaking 1
Gromit 0 eating 2
Gromit 1 eating 2
Gromit 2 eating 2
Gromit 3 eating 2
Gromit 4 eating 2
Gromit 0 sleeping z 3
Gromit 1 sleeping z 3
Gromit 2 sleeping z 3
Gromit 3 sleeping z 3
Gromit 4 sleeping z 3
Gromit 0 sitting
Gromit 1 sitting
Gromit 2 sitting
Gromit 3 sitting
Gromit 4 sitting
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.