簡體   English   中英

模板繼承C ++迭代器

[英]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);
} ///:~

我不太明白為什么編譯iterator在這里抱怨iterator 由於此代碼段代碼基於模板實現了一個SequenceWithApply類。 在這種情況下, SequenceWithApply實際上是vector的基類。 迭代器應該在此基類中可見。 我真的很感謝有人可以幫助我解決這個問題。

編譯iterator在第一階段查找時尋找iterator ,這是在模板實例化之前進行的。 為了知道該類是從哪種類型派生的,必須實例化該模板(以便Seq<T*>是實際類型)。 因此,編譯器從未在基類中找到iterator

您可以通過兩種簡單的方法解決此問題:

一次性:

typename Seq<T*>::iterator

派生類中的類型別名:

using iterator = typename Seq<T*>::iterator;

所有這些明確指定了iterator所屬的類型,並在知道SeqT的第二個查找階段中對其進行查找。 有關typename更多信息

您可以對功能執行相同的操作:

一次性:

Seq<T*>::begin()
this->begin() // if inside a member function

使用聲明:

using Seq<T*>::begin;

您正在使用的書可能已過時。 如今,c ++已朝着使用自由函數實現更好的去耦的方向發展。

例:

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

預期輸出:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM