Calling a template method from another template method in C++?

thewalrusnp

I am currently having an issue with templated methods. I have this public class implementing a template method:

namespace Private { class InternalClass; }

namespace Public
{
    class PublicClass
    {
    public:
        PublicClass();
        virtual ~PublicClass();

        template<class T>
        bool Add(bool primary);

    private:
        Private::InternalClass* _pInternal;
    };

    template<class T>
    bool PublicClass::Add(bool primary) { return _pInternal->Add<T>(primary); }
}

The internal class is implemented that way:

namespace Private
{
    class InternalClass
    {
    public:
        InternalClass();
        virtual ~InternalClass();

        template <class T>
        bool Add(bool primary);
    };

    template<class T>
    bool InternalClass::Add(bool primary) { return false; }
}

As this internal class header won't be available with the provided sources, I must class forward it within the PublicClass header and I add the include to PrivateClass.h inside the PublicClass.cpp file.

1) Any idea why I would be getting the following error:

error : member access into incomplete type 'Private::InternalClass' / note: forward >declaration of 'Private::InternalClass'

2) What would be the best way of hiding my PublicClass::Add() implementation?

UPDATED

Reason for error at 1) is because of this as stated by Cornstalks.

For 2), how can I hide my implementation without including PrivateClass.h within the PublicClass header file?

Piotr Skotnicki

You have encountered a very interesting problem - you want to implement the PImpl idiom where the privately implemented class has a template method. Well, this can be solved, meaning you CAN hide the template's implementation, but only when you know which types will be used to instantiate your Add<T> method in your program.

Say, your template will work only with types AClass and BClass. Then you can split your files as follows (comments are inlined):

File public.h:

#ifndef PUBLIC_H
#define PUBLIC_H

// Forward declaration ! It's sufficient in this case !
namespace Private { class InternalClass; }

// Declare all classes your Add<T> method should work with
struct AClass {};
struct BClass {};

namespace Public
{
    class PublicClass
    {
    public:
        PublicClass() {}
        virtual ~PublicClass() {}

        template <typename T>
        bool Add(bool primary); // DO NOT implement this method, just declare

    private:
        Private::InternalClass* _pInternal;
    };

    // "Explicit instantiation declarations", for each type the method will work with:
    extern template bool PublicClass::Add<AClass>(bool primary);

    extern template bool PublicClass::Add<BClass>(bool primary);
}

#endif

File public.cpp:

#include "public.h"

// NOTE: this is hidden in CPP file, noone will see your implementation
namespace Private
{
    class InternalClass
    {
    public:
        InternalClass() {}
        virtual ~InternalClass() {}

        template <typename T>
        bool Add(bool primary);
    };

    // Magic! Here is the actual implementation of your private method
    template <typename T>
    bool InternalClass::Add(bool primary)
    {
        return false;
    }
}

namespace Public
{
    // Original definition moved to CPP file !
    template <typename T>
    bool PublicClass::Add(bool primary)
    {
        return _pInternal->Add<T>(primary);
    }

    // And again list the allowed types, this time using "explicit instantiation definitions"
    template bool PublicClass::Add<AClass>(bool primary);

    template bool PublicClass::Add<BClass>(bool primary);
}

File main.cpp:

#include "public.h"

int main()
{
    Public::PublicClass pc;
    pc.Add<AClass>(true); // works !
    pc.Add<BClass>(false); // works !

    // pc.Add<int>(true); linker error as expected,
    // becuase there is no explicit instantiation for Add<int>

    return 0;
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Calling a static template method from a template function

From Dev

calling method in template class in template member function of another class

From Dev

Calling service method from a directive template

From Dev

Multiple times method calling from angular template

From Dev

Calling virtual method of base template from derived variadic template class

From Dev

c++ method leak from another template class and namespace

From Dev

CLI/C++ Interface class, Generic method calling template method

From Dev

Template method calling template method of another class doesn't want to compile

From

Go template: calling method on $variable in template

From Dev

Calling a template method on a class template parameter

From Dev

calling a java method in velocity template

From Javascript

Calling service method in a Vue template

From Dev

Calling method of template base class

From Java

Calling a method from another method

From Dev

calling a static method from template class from other file C++

From Dev

False clang error when calling a template template method with a template that is in a namespace

From

Calling method from a Angular 2 class inside template

From Dev

C++ generic template method name from template parameter

From Dev

Calling derived template class method from base non-template class

From Dev

Template Method calling super and use implementation

From Dev

calling a template method results in no match for 'operator<'

From Dev

Calling method on Template variables giving "undefined" exception

From Dev

Calling Model method inside template file

From Dev

Issue with calling static template method inside a template class

From

Call a method from a Go template

From Dev

Pointer to method from template arguments

From Dev

Calling one method from another method in Python

From Java

Calling method of Another class from run() method

From Dev

Calling an impl method from another impl method

Related Related

  1. 1

    Calling a static template method from a template function

  2. 2

    calling method in template class in template member function of another class

  3. 3

    Calling service method from a directive template

  4. 4

    Multiple times method calling from angular template

  5. 5

    Calling virtual method of base template from derived variadic template class

  6. 6

    c++ method leak from another template class and namespace

  7. 7

    CLI/C++ Interface class, Generic method calling template method

  8. 8

    Template method calling template method of another class doesn't want to compile

  9. 9

    Go template: calling method on $variable in template

  10. 10

    Calling a template method on a class template parameter

  11. 11

    calling a java method in velocity template

  12. 12

    Calling service method in a Vue template

  13. 13

    Calling method of template base class

  14. 14

    Calling a method from another method

  15. 15

    calling a static method from template class from other file C++

  16. 16

    False clang error when calling a template template method with a template that is in a namespace

  17. 17

    Calling method from a Angular 2 class inside template

  18. 18

    C++ generic template method name from template parameter

  19. 19

    Calling derived template class method from base non-template class

  20. 20

    Template Method calling super and use implementation

  21. 21

    calling a template method results in no match for 'operator<'

  22. 22

    Calling method on Template variables giving "undefined" exception

  23. 23

    Calling Model method inside template file

  24. 24

    Issue with calling static template method inside a template class

  25. 25

    Call a method from a Go template

  26. 26

    Pointer to method from template arguments

  27. 27

    Calling one method from another method in Python

  28. 28

    Calling method of Another class from run() method

  29. 29

    Calling an impl method from another impl method

HotTag

Archive