1

这就是我想使用模板做的事情:

struct op1
{
   virtual void Method1() = 0;
}

...

struct opN
{
   virtual void MethodN() = 0;
}

struct test : op1, op2, op3, op4
{
    virtual void Method1(){/*do work1*/};
    virtual void Method2(){/*do work2*/};
    virtual void Method3(){/*do work3*/};
    virtual void Method4(){/*do work4*/};
}

我想要一个简单地从提供这些方法声明的模板类派生的类,同时使它们成为虚拟的。这是我设法想出的:

#include <iostream>

template< size_t N >
struct ops : ops< N - 1 >
{
protected:
    virtual void DoStuff(){ std::cout<<N<<std::endl; };
public:
    template< size_t i >
    void Method()
    { if( i < N ) ops<i>::DoStuff(); } 
    //leaving out compile time asserts for brevity
};

template<>
struct ops<0>
{
};

struct test : ops<6>
{
};

int main( int argc, char ** argv )
{
  test obj;
  obj.Method<3>(); //prints 3
  return 0;
}

但是,正如您可能已经猜到的那样,我无法覆盖我继承的 6 种方法中的任何一种。我显然在这里遗漏了一些东西。我的错误是什么?不,这不是家庭作业。这是好奇心。

4

3 回答 3

3

经 GCC 4.3 测试。甚至不知道我为什么要花时间在这上面:-/

#include <iostream>

template <std::size_t N>
struct mark
{ };

template <std::size_t N>
struct op : op <N - 1>
{
  virtual  void  do_method (const mark <N>&) = 0;
};

template <>
struct op <1>
{
  virtual  void  do_method (const mark <1>&) = 0;
};

struct test : op <2>
{
  template <std::size_t K>
  void
  method ()
  {  do_method (mark <K> ());  }

  virtual  void do_method (const mark <1>&)
  {  std::cout << "1\n";  }

  virtual  void do_method (const mark <2>&)
  {  std::cout << "2\n";  }
};

int
main ()
{
  test  x;

  x.method <1> ();
  x.method <2> ();
}

我不知道如何将“美化器”method()模板功能移出test.

于 2010-04-25T22:13:11.923 回答
1
template< size_t N >
struct ops : ops< N - 1 >

这编码了一个无限循环。当 N 达到 0 时,递归不会停止。在主模板之后立即为结束情况添加一个特化:

template<>
struct ops<0> {}

另外,这有什么作用?为什么不直接打电话ops<i>::DoStuff()呢?

template< size_t i >
void Method()
{ if( i < N ) ops<i>::DoStuff(); } 
于 2010-04-25T22:10:10.017 回答
1

模仿你最初的愿望:

#define MAKE_OPS(N) template<> struct Ops<N> : Ops<N-1> { virtual void Method##N() = 0; }

template<int N>
struct Ops;

template<>
struct Ops<0> { };

MAKE_OPS(1);
MAKE_OPS(2);
template<> struct Ops<3> : Ops<2> { virtual void Method3() { std::cout << "3" << std::endl; } };
MAKE_OPS(4);
MAKE_OPS(5);
MAKE_OPS(6);

struct Test : Ops<3> {
    virtual void Method1() { std::cout << 1 << std::endl; }
    virtual void Method2() { std::cout << 2 << std::endl; }
};
于 2010-04-25T22:15:17.160 回答