Home > Backend Development > C++ > Why do public members of a base class become invisible when inheriting a class template, and what are the solutions to this problem?

Why do public members of a base class become invisible when inheriting a class template, and what are the solutions to this problem?

Susan Sarandon
Release: 2024-11-02 15:13:30
Original
333 people have browsed it

Why do public members of a base class become invisible when inheriting a class template, and what are the solutions to this problem?

Avoiding Public Member Invisibility and Code Bloat in Inherited Class Templates

Object-oriented programming relies on the inheritance of protected and public class members. In non-templated environments, this inheritance is straightforward. However, when introducing class templates, a fundamental issue arises: public members of the base class become invisible to the derived class template.

The Problem

Consider the following example:

<code class="cpp">class CBase
{
public:
    int Fn1(void) { ... }
};

class CDerived : public CBase
{
public:
    int FnSum(void) { ... CBase::Fn1(); ... }
};</code>
Copy after login

When templating this code, the Fn1() member of CBase disappears from the perspective of CDerived:

<code class="cpp">template<unsigned int BYTES>
class CBase
{
public:
    int Fn1(void) { ... }
};

template<unsigned int BYTES>
class CDerived : public CBase<BYTES>
{
public:
    int FnSum(void) { ... Fn1(); ... } // Error: Fn1 not found!
};</code>
Copy after login

Solutions

Various solutions exist to address this issue:

Solution 1 (Verbose Prefixing):

<code class="cpp">int FnSum(void) {
    return CBase<BYTES>::Fn1() + CBase<BYTES>::Fn2() + CBase<BYTES>::Arr[0];
}</code>
Copy after login

However, this approach introduces excessive code bloat when referencing multiple members.

Solution 2 (Verbose "this->" Prefixing):

<code class="cpp">int FnSum(void) {
    return this->Fn1() + this->Fn2() + this->Arr[0];
}</code>
Copy after login

Similar to Solution 1, but slightly less verbose.

Solution 3 (Using Statement):

<code class="cpp">using CBase<BYTES>::Arr;
using CBase<BYTES>::Fn1;
using CBase<BYTES>::Fn2;</code>
Copy after login

This allows direct access to CBase members without additional prefixing.

Solution 4 (Permissive Mode):

<code class="cpp">// Compiler flags: /permissive- (MSVC), -fpermissive (GCC/Cl), -fno-implicit-templates (Clang)</code>
Copy after login

Disables strict C compliance, resolving the issue but may introduce portability concerns.

A Better Solution

While Solution 3 is cleaner than the others, it still requires repetitive "using" statements. Macros can simplify this:

<code class="cpp">#include <boost/preprocessor.hpp>

#define USING_ONE(r, base, member) using base::member;

#define USING_ALL(base, ...) BOOST_PP_SEQ_FOR_EACH(USING_ONE, base, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))

#define USING_CBASE(param) USING_ALL(CBase<param>, Arr, Fn1, Fn2, Fn3, Fn4, Fn5)</code>
Copy after login

In the derived class:

<code class="cpp">USING_CBASE(BYTES); // Makes all mentioned CBase members directly accessible</code>
Copy after login

This approach significantly reduces code bloat and duplication.

The above is the detailed content of Why do public members of a base class become invisible when inheriting a class template, and what are the solutions to this problem?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template