简体   繁体   English

从基类模板虚拟方法而不是使用重载

[英]Template a virtual method from base class instead of use overloading

I got strange code and have to extend it.我得到了奇怪的代码,必须扩展它。 But instead of copy paste many many times i decided to create a template.但是我决定创建一个模板而不是多次复制粘贴。 But get caught by a terrible rock.但是被一块可怕的岩石抓住了。

Here is an example code:这是一个示例代码:

template<typename T>
class anyClass {};

template<typename T>
class Outer : public anyClass<T>
{
public:
   using value_t = T;
   class Inner
   {
      virtual void foo(value_t);
   };
};

class specializer : protected Outer::Inner
{
   virtual void foo(int) override {}
}

I have to extend virtual void foo(value_t) in specializer.我必须在 specializer 中扩展virtual void foo(value_t)

Example:例子:

class specializer : protected Outer::Inner
{
   virtual void foo(int) override {}
   virtual void foo(float) override {}
   virtual void foo(string) override {}
   virtual void foo(bar) override {}
   // And so on...
 }

Question 1: Why works the example, although class specializer : protected Outer::Inner miss a param?问题 1:尽管class specializer : protected Outer::Inner错过了一个参数,但为什么该示例有效?

All overloadings do nearly the same.所有的重载几乎都是一样的。 I created already the function.我已经创建了该功能。

template<typename anyType>
void meow( anyType )
{
/***/
}

My problem is here:我的问题在这里:

virtual void foo(anytype value) //<< replace anytype with what?
{
   meow<anytype>( value );
}

I need the type Outer::value_T but i don't know how to get it.我需要类型Outer::value_T但我不知道如何获得它。

Question 2: How can i use meow by calling foo ?问题 2:如何通过调用foo来使用meow

Feel free to ask for more information.随时询问更多信息。

UPDATE更新

I looked again in the origin code and realised, that i've overlooked an important using/typedef.我再次查看原始代码并意识到,我忽略了一个重要的 using/typedef。 The working code looks like:工作代码如下所示:

class specializer : protected Outer<int, float, string, bar>::Inner //Yes a variadic-template
{
   virtual void foo(int) override {}
   virtual void foo(float) override {}
   virtual void foo(string) override {}
   virtual void foo(bar) override {}
   // And so on...
 }

So Question 1 is solved .所以问题1解决了

Why works the example, although class specializer : protected Outer::Inner miss a param?尽管类专业化器:protected Outer::Inner 错过了一个参数,为什么这个例子有效?

The example does not work .这个例子工作 It does not work because Outer is not a type.它不起作用,因为Outer不是一种类型。 Also, you override multiple overloads of foo even though inner has only one foo .此外,即使inner只有一个foo ,您也覆盖了foo多个重载。 There are several syntax errors too.还有几个语法错误。 If it appears to work, then the compiler is doing something non-standard.如果它看起来有效,那么编译器正在做一些非标准的事情。

About your second question:关于你的第二个问题:

virtual void foo(anytype value) //<< replace anytype with what?

You replace it with the type whose overload you intend to override.您将其替换为您打算覆盖其重载的类型。 For example, if you intend to override foo(int) , then replace anytype with int .例如,如果您打算覆盖foo(int) ,则将anytype替换为int

Question 2: How can i use meow by calling foo ?问题 2:如何通过调用 foo 来使用 meow ?

Simply call meow in foo .只需在foo调用meow

You would have to make specializer a template class.您必须将specializer设为模板类。

#include <iostream>

template<typename T> void meow(T x) 
{
    std::cout << x << std::endl;
}

template<typename T>
class anyClass {};

template<typename T>
class Outer : public anyClass<T>
{
public:
   using value_t = T;
   class Inner
   {
      virtual void foo(Outer<T>::value_t);
   };
};

template<typename T>
class specializer : protected Outer<T>::Inner
{
   virtual void foo(T x) override 
   {
       meow(x);
   }
};

I wonder how this would help you to change the behavior in Outer or anyClass because you have not shown code which shows where and how Inner is actually used.我想知道这将如何帮助您更改OuteranyClass的行为,因为您没有显示显示实际使用Inner位置和方式的代码。 Without that, it's just guessing.没有它,它只是猜测。

I have the feeling that what you are actually trying to achieve is to pass a function (or Strategy?) to you Outer class, represented by Inner in your code.我有一种感觉,您实际上想要实现的是将函数(或策略?)传递给您的Outer类,在您的代码中由Inner表示。 That would be better done by passing it as a template argument.通过将其作为模板参数传递会更好地完成。

template<typename T>
class anyClass {};

template<typename T, typename Inner = meow<T>>
class Outer : public anyClass<T>
{
public:
   using value_t = T;

   // somewhere in your code
   Inner i;
   i.meow( any_value );
};

You can also pass a std::function to the constructor.您还可以将std::function传递给构造函数。 template class anyClass {};模板类 anyClass {};

template<typename T>
class Outer : public anyClass<T>
{
public:
   using value_t = T;

   Outer( std::function<void (value_t)> inner);

   // somewhere in your code
   i.meow( any_value );

   std::function<void (value_t)> i;
};

Originally I simplyfied a little bit to much.最初我简单化了一点点。 Here is the compileable example of my problem: http://ideone.com/9U7J1a I removed all unconducive code.这是我的问题的可编译示例: http ://ideone.com/9U7J1a 我删除了所有无用的代码。 I know the design is horrible but i have no influence on it.我知道设计很糟糕,但我对它没有影响。

class bar {};
class string {};

template<typename _T>
class ModelContainer 
{
    public:
    using value_type = _T;

   class Delegate {
     public:
       virtual void foo( value_type value);
   }; 
};

template< typename... _Ts >
class ModelManager__AbstractBase : protected ModelContainer< _Ts >...
{
public:
  class Delegate : public ModelContainer< _Ts >::Delegate... {
  public:
    virtual ~Delegate( ) = default;
  };
};


using ModelManager__Base = ModelManager__AbstractBase<
    int,
    float,
    string,
    bar
>;

class ModelManager : public ModelManager__Base {
    /* Some functions */
};

class spezializer : ModelManager::Delegate
{
    public:
    virtual ~spezializer() = default;
        //Uncommend to see my error  
       // virtual void foo( value_type value) override // << value_type unknown
       // {/* Calling everytime the same method, no matter which value_type*/}
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM