访问从模板类派生的类中的基本成员函数 [英] Accessing base member functions in class derived from template class

查看:194
本文介绍了访问从模板类派生的类中的基本成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在我的工作中开发一个库,我设计了一个复杂的继承,包括模板类并从中派生出来。
我的问题是基本模板类有虚拟重载运算符,它接受2个参数并返回一些值。在基类中,实现了这个运算符,并且大多数派生类都没有重新实现这个运算符。

I am developing a library at my work and I have designed a complicated inheritance that includes template classes and deriving from them. My problem is that a base template class has virtual overloaded operator that takes 2 arguments and returns some value. In base class this operator is implemented and most of derived classes does not reimplement this operator.

其他一些类使用派生类进行某些工作并利用它们的运算符成员函数。只要派生类没有其他重载运算符,即使使用不同数量的参数,一切都可以正常工作。如果有的话,那么使用它作为 object()无法访问基类运算符,因为编译器找不到合适的成员函数(抱怨参数计数不匹配)。

Some other class uses derived classes for some work and make use of their operator member function. Everything works just fine as long as derived class has no other overloaded operator, even with different number of arguments. If one does then the base class operator is not accessible using it as object() because compiler can not find proper member function (complains about argument count missmatch).

指定基类的默认模板参数是否无关紧要。派生类的定义顺序也不会改变哪个运算符导致问题(它总是 SpecificDerived class)。

It does not matter wether default template arguments for base class was specified or not. Also order of definitions of derived classes does not change which operator cause the problem (it is always SpecificDerived class).

下面我提出简化问题。

示例已简化

基类定义:

template<class ret_t>
class TemplateBase2
{
public:
    virtual ~TemplateBase2()
    {
    }

    virtual ret_t memberFunc(ret_t x)
    {
        return x * 2;
    }
};

派生类定义的用户:

template <class worker, class ret_t>
ret_t gobble(worker w, float f)
{
    return w.memberFunc((ret_t)f);
}

派生类:

class SpecificDerived2: public TemplateBase2<float>
{
public:
    float memberFunc()
    {
        return 3.14;
    }
};

主要功能:

#include <iostream>
#include "TemplateBase2.h"

using namespace std;

int main()
{
    SpecificDerived2 sd2;

    cout << "sd2: " << gobble<SpecificDerived2, float>(sd2, 3.14f) << endl; 
    return 0;
}

编译器退出时出错,声称没有匹配从 gobble 函数调用'SpecificDerived2 :: memberFunc(float)'的函数。只有当派生类或基类有两个具有相同名称但不同参数的重载函数时才存在问题。

Compiler exits with error claiming that there is no matching function for call to 'SpecificDerived2::memberFunc(float)' from gobble function. Problem exists only when either derived or base class has two overloaded functions of the same name, but different arguments.

我正在使用MinGW32 4.8.1并支持c ++ 11 。

I am using MinGW32 4.8.1 with c++11 support.

推荐答案

当类模板派生自基类模板时,基类成员在派生类模板定义中不可见。 (这是有道理的;直到你专攻,没有类,所以没有成员。明确的专业化总是可以改变任何给定模板类的含义。)

When a class template derives from a base class template, the base members are not visible in the derived class template definition. (This makes sense; until you specialize, there is no class, and so there are no members. Explicit specializations can always change the meaning of any given template class.)

换句话说,基本模板成员名称是从属名称,在模板定义查找的第一阶段没有查找。

In other words, the base template member names are dependent names and not looked up in the first phase of template definition lookup.

有三种方法可以解决这个问题。让我们通过一个简单的例子来说明:

There are three ways to get around this. Let's make it concrete with a quick example:

template <typename T> struct Foo
{
    int data;
    using type = const T &; 
    void gobble() const;
    template <int N> void befuddle();
};

template <typename T> struct X : Foo<T> { /* ... */ };

现在在派生类模板定义的上下文中,你可以......

Now in the context of the derived class template definition, you can...


  1. 限定名称:

  1. Qualify the name:

Foo<T>::data = 10;
typename Foo<T>::type x;
Foo<T>::gobble();
Foo<T>::template befuddle<10>();


  • 使用

    this->data = 10;
    this->gobble();
    this->template befuddle<10>();
    

    (这不适用于类型名称。)

    (This doesn't work for type names names.)

    使用声明:

    Use a using declaration:

    using Foo<T>::data;
    using Foo<T>::gobble;
    using type = typename Foo<T>::type;
    
    data = 10;
    gobble();
    

    (这不适用于模板名称。)

    (This doesn't work for template names.)






    更新:编辑后,问题完全不同。模板根本不起作用,因为问题不包含模板,只包含类。发生的事情很简单,成员函数在派生类隐藏基类中同名的成员函数中,因此存在 SpecificDerived2 :: memberFunc 隐藏基本成员函数。简单的解决方案是使用声明使用取消隐藏同名基本成员:


    Update: After your edit, the question is entirely different. Templates don't play a role at all here, since the problem doesn't contain templates, only classes. What's happening is the simple fact that member functions in a derived class hide member functions of the same name in base classes, so the presence of SpecificDerived2::memberFunc hides the base member function. The simple solution is to unhide base members of the same name with a using declaration:

    class SpecificDerived2 : public TemplateBase2<float>
    {
    public:
        using TemplateBase2<float>::memberFunc;
    //  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
        float memberFunc()
        {
            return 3.14;
        }
    };
    

    这篇关于访问从模板类派生的类中的基本成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆