1

I have a pure virtual function defined in a class as below:

   template <typename T>
   class PositioningMethod {

   public:
       virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) = 0;
   };

and implementing it in ParticleFilter as below:

class ParticleFilter:public PositioningMethod<T> {

           public:
               virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) {
              /*Some code and return*/
           return ApproximatePosition::from(xxxx, xxxx, xxxx());

           }
};

but getting below errors:

    "ParticleFilter<KnownBluetoothBeacon<CartesianLocation>, RadioProximity<BluetoothBeacon>
   >::getPosition(std::__1::list<RadioProximity<BluetoothBeacon>*, std::__1::allocator<RadioProximity<BluetoothBeacon>*> >&)",    referenced from:
             vtable for RadioProximityParticleFilter in lib.a(RadioProximityParticleFilter.o)
         "ParticleFilter<KnownBluetoothBeacon<CartesianLocation>, RadioProximity<BluetoothBeacon>
   >::ParticleFilter(std::__1::list<KnownBluetoothBeacon<CartesianLocation>,    std::__1::allocator<KnownBluetoothBeacon<CartesianLocation> > >&,    double)", referenced from:
             RadioProximityParticleFilter::RadioProximityParticleFilter(std::__1::list<KnownBluetoothBeacon<CartesianLocation>,    std::__1::allocator<KnownBluetoothBeacon<CartesianLocation> > >&,    double) in lib.a(RadioProximityParticleFilter.o)
       ld: symbol(s) not found for architecture arm64

I know vtable error generally occurs on non-implementing pure virtual functions, but in my case it is same. Any idea where I may be wrong?

Note: The above errors I am getting while integrating my C++ code with objective C in iOS. While in C++ its working fine

This below line is causing the errors in ViewController.mm:

RadioProximityParticleFilter *obj = new RadioProximityParticleFilter (*asList,50);
Tarun
  • 329
  • 1
  • 4
  • 16
  • What is the point of making a pure virtual function in a template class? Why not just leave it out of the base class. The compiler will already generate an error if it cannot find the method when you try to use it in some template function, and you could make a static assert that the member is there if you want it to fail very loudly. (There are some rules in the standard about not mixing template and virtual, although I don't remember exactly what they are...) – Chris Beck Jun 23 '16 at 04:43
  • Template functions must be implemented in the header. The compiler must see the function body at the point where it is used. My guess would be, your put the implementation into a source file. – Igor Tandetnik Jun 23 '16 at 04:57
  • The `RadioProximityParticleFilter` class, which is derived from `ParticleFilter`, does int implement `getPosition` so the entry in `RadioProximityParticleFilter`'s vtable refers to `ParticleFilter::getPosition`. The linker isn't finding this function (I don't know why) and generating the error. – 1201ProgramAlarm Jun 23 '16 at 04:57
  • @ChrisBeck I have done some research and found that its legal to use pure virtual with class templates. But I do not understand the below line in the below link: http://stackoverflow.com/a/8919588/4225953 "_With most standard C++ implementations, this is fine, because when the template is instantiated the virtual function ends up being one single function. Consequently, the number of slots needed in the vtable can be known within the translation unit, so a vtable can be generated._" – Tarun Jun 23 '16 at 05:17
  • @IgorTandetnik I have Template definition in header only. Can you suggest which class are you talking about? Template implementation however consist of generics implementation using SFINAE. – Tarun Jun 23 '16 at 05:21
  • I mean the implementation of `ParticleFilter::getPosition` of course, the function the linker complains about. Actually, upon closer inspection, the linker can't find `ParticleFilter` constructor either - virtual functions are a red herring. – Igor Tandetnik Jun 23 '16 at 05:30
  • Please provide a [mcve], a minimal set of code that generates the error above. At this point we still have to guess what is causing your error, because details you are omitting matter. Please follow the link and improve your question. This is not a request to copy paste more code. – Yakk - Adam Nevraumont Jun 23 '16 at 07:49
  • @Yakk: I will keep this in mind going forward – Tarun Jun 24 '16 at 06:55

1 Answers1

2

I completed your code to use it in my MS VS 2013 test project, and it just works - here is the full listing:

#include <iostream>
#include <list>

using namespace std;

class ApproximatePosition
{
public:
    static ApproximatePosition *from( int a, int b, int c)
    {
        cout << "from called." << endl;
        return NULL;
    }
};

class ListElem{};

template <typename T>
class PositioningMethod 
{
    public:
        virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals) = 0;
};

template <typename T>
class ParticleFilter :public PositioningMethod<T>
{

    public:
        virtual ApproximatePosition *getPosition(std::list<T*> &observedRadioSignals)
        {
            /*dummy input and return*/
            int a = 0, b = 0, c = 0;
            cout << "getPosition called." << endl;
            return ApproximatePosition::from( a, b, c );// xxxx, xxxx, xxxx());         
        }
};

int main()
{
    PositioningMethod<ListElem> *pm = new ParticleFilter<ListElem>();

    std::list<ListElem*> l;
    pm->getPosition( l );

}

The output is:

getPosition called.
from called.
Trantor
  • 768
  • 1
  • 8
  • 27