spot7.org logo
Home PHP C# C++ Android Java Javascript Python IOS SQL HTML Categories

Virtual template function visitor workaround with template derived classes


One possible solution was mentioned by Jarod42, namely to specify all possibly occuring types. Usually, however, you want to give a standard implementation taking a Base* as well, and overload this only when required.

struct Type1 {};
//...
struct TypeN {};

struct Visitor
{
    virtual ~Visitor() {}

    virtual void visit (Base*) const = 0;
    virtual void visit (Derived<Type1>* d)
const { visit(static_cast<Base*>(d)); };
    //...
    virtual void visit (Derived<TypeN>* d)
const { visit(static_cast<Base*>(d)); };
};


struct FooVisitor : public Visitor
{
    virtual void visit (Base* base) const override
    {
        std::cout<<"visiting base
class."<<std::endl;
    }

    //further definitions for those types that
require a special implementation
    virtual void visit (Derived<TypeN>* d)
const override
    {
        std::cout<<"visiting class of type
Derived<TypeN>."<<std::endl;
    }
};

DEMO


EDIT: Here is another possibility using basic double dispatch:

struct Visitor
{
    virtual ~Visitor() {}

    virtual void visit (Base*) const = 0;
};

struct FooVisitor : public Visitor
{
    virtual void visit (Base* base) const override
    {
        if(Derived<TypeN>* d =
dynamic_cast<Derived<TypeN>*>(base))
        {
            std::cout<<"visiting class of
type Derived<TypeN>."<<std::endl;
        }
        else
        {
            std::cout<<"visiting base
class."<<std::endl;
        }
    }
};

It releases you from declaring each possible variable type in the base class, but is probably less efficient than the previous solution.

This brute-force approach has some other disadvantages, which are collected in chapter 11 of Alexandrescu's book. You can also read there how to overcome these disadvantages by using a static dispatcher. Basically there you just enter once the types you want to consider for dispatching, and let the code create the above logic.

DEMO


Categories : C++

Related to : Virtual template function visitor workaround with template derived classes
Is an unexpanded parameter pack in a function signature template argument for a class template allowed? (Possible VS2013 bug)
Looks very much like a VS bug to me, since that's a perfectly valid pattern expansion to use. VS's variadics implementation is extremely flaky, in my experience. That said, this primary template: template <typename ...Args> struct MakeTupleOfTypes; should really not be varadic, since the template only accepts one TypeList: template <typename ArgsList> struct MakeTupleOfTypes;

Categories : C++
How to call a Functor template class with template function
Looks like a bug in MSVC. It thinks &addValueTemplate<unsigned int> is a function, not a function pointer. Use an intermediate function pointer variable: unsigned int (*av)(unsigned int const&) = &addValueTemplate; j = unary_apply(av, i); Or use this to fool MSVC: template <typename T> T* identity(T* x) { return x; } j = unary_apply(identity(&addValueTemplate<un

Categories : C++
Derrived Classes and Template Arguments
I'm not sure I completely understand your question, but no matter how I think of it, changing ParentListElementClass appears hard to avoid. You could try something on these lines.. template<typename T, typename U> struct MyTypedefCase { typedef T<U> _type; }; Then rewrite ParentListElementClass as template <class ParentType, typename T, typename U> class ParentListElemen

Categories : C++
Meteor + Iron-Router - how do I update my template's data context in response to events the user generates in my template?
Yes: Router.route('audit', { path: '/audit/:audit_id/', template: 'audit', onRun: function() { Session.set('audit', Audits.findOne(this.params.audit_id)); Session.set('lineitems', LineItems.find(JSON.parse(audit.query)).fetch()); } data: function() { if (this.ready()) { return { audit_obj: Session.get('audit'),

Categories : Meteor
How to insert or render a template after another template is rendered in Meteor?
var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; script.onreadystatechange = function() { // if (this.readyState == 'complete') { callFunctionFromScript(); } } script.src = 'path/to/your-script.js'; head.appendChild(script); u can directly apped it into html head tag inside Template.layoutHeader.rendered = f

Categories : Meteor
Recently Add
C++: error C2143: syntax error : missing ';' before '<'
Converting 2s compliment to a decimal. Output is double
how do you compare a string to a vector value?
Converting a long double to double with upward (or downward) rounding
C++: operator<< overloading in the nested classes
Unclear behavior with csv processing using getline
C++ Visual Studio Error: IntelliSense: expected a statement
Game of Nim - showing the remaining numbers and letting a player pick their name?
malloc 1D array in struct
How to create an array of smart pointers?
c++ swapping unique_ptr's
Functions as arguments
Any Fast & Efficient way to generate a 3D Grid?
Is string[] not a type?
C++ typeid(x).name() returns ph
Counting / Printing Path - From (1,1) to (m, n)
C++ input function that calls itself
Error: array must be initialized with a brace-enclosed initializer
SDL_ConvertSurface() causes break
C++ std deviation function?
libcURL Progress Function not being called
What is QList's maximum size?
Run batch with C++
Read a file and write its contents to another C++
extract from stringstream into 2D vector
How to stop Scons adding lib infront of a shared library
Blocking vs non-blocking mode in TCP sockets using C++
SDL2 toggle SDL_WINDOW_RESIZABLE state for fake fullscreen
How can I assign value to specific vector's index?
Operator Overloading with Constant Iterators
© Copyright 2017 spot7.org Publishing Limited. All rights reserved.