Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I make a typedef or alias for a template function that can also be used in friend function declarations?

If I have something like this:

mytemplates.h

#ifndef MYTEMPLATES_H
#define MYTEMPLATES_H

#include <iostream>
#include <memory>
#include <string>

class BaseClass;
// Alias (non-working) version:
//class DerivedClass1;

namespace MyTemplates
{
    typedef std::unique_ptr<BaseClass> object_up;
    
    template<typename SomeDerivedClass>
    object_up createFromIntFloat(int intParam, float floatParam)
    {
        SomeDerivedClass *newObject_raw = new SomeDerivedClass(intParam, floatParam);

        object_up uniqueObject {newObject_raw};

        std::cout << "createFromIntFloat." << "\n";

        return uniqueObject;
    }
    // Alias (non-working) version:
    //using createFromIntFloatPtrType = object_up(*)(int intParam, float floatParam);

    template<typename SomeDerivedClass>
    object_up createFromString(std::string stringParam)
    {
        SomeDerivedClass *newObject_raw = new SomeDerivedClass(stringParam);

        object_up uniqueObject {newObject_raw};

        std::cout << "createFromString." << "\n";

        return uniqueObject;
    }
    // Alias (non-working) version:
    //using createFromStringPtrType = object_up(*)(std::string stringParam);  

    // Alias (non-working) version:
    // createFromStringPtrType createDerivedClass1 =  createFromString<DerivedClass1>;
}

#endif // MYTEMPLATES_H

baseclass.h

#ifndef BASECLASS_H
#define BASECLASS_H

class BaseClass
{
protected:
    BaseClass(){};
};

#endif // BASECLASS_H

derivedclass1.h

#ifndef DERIVEDCLASS1_H
#define DERIVEDCLASS1_H

#include "baseclass.h"
#include "mytemplates.h"

class DerivedClass1 : public BaseClass
{
    std::string stringParam;
protected:
    DerivedClass1(std::string aStringParam) : BaseClass(), stringParam(aStringParam) {};

    // Alias (non-working) version:
    // friend MyTemplates::object_up MyTemplates::createDerivedClass1(std::string stringParam);

    // Non-alias version:
    friend MyTemplates::object_up MyTemplates::createFromString<DerivedClass1>(std::string stringParam);
};

#endif // DERIVEDCLASS1_H

main.cpp

#include "mytemplates.h"
#include "derivedclass1.h"

int main(int argc, char *argv[])
{
    // Alias (non-working) version:
    // MyTemplates::object_up uniqueClass1 = MyTemplates::createDerivedClass1("creation info for class 1");
    
    // Non-alias version:
    MyTemplates::object_up uniqueClass1 = MyTemplates::createFromString<DerivedClass1>("creation info for class 1");
}

I would like to create some kind of alias like the Alias (non-working) version on the above code so that I could use this alias – createDerivedClass1 – both in direct calling like in main.cpp and in friend declarations like in derivedclass1.h

How can I change the code above from the Non-alias version to the Alias version and make it work?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Aliases are for types because types are not first class objects in C++. But you do not need aliases for plain functions because you can simply use function pointers.

But a function pointer is just a pointer and you must declare the real function to be friend. It all boil down to:

...
class DerivedClass1 : public BaseClass
{
    std::string stringParam;
protected:
    DerivedClass1(std::string aStringParam) : BaseClass(), stringParam(aStringParam) {};

    // Alias (non-working) version:
    //friend MyTemplates::object_up MyTemplates::createDerivedClass1(std::string stringParam);

    // Non-alias version:
    friend MyTemplates::object_up MyTemplates::createFromString<DerivedClass1>(std::string stringParam);
};

namespace MyTemplates {
    object_up(*createDerivedClass1)(std::string) = createFromString<DerivedClass1>;
}

int main(int argc, char* argv[])
{
    // Alias (non-working) version:
    MyTemplates::object_up uniqueClass1 = MyTemplates::createDerivedClass1("creation info for class 1");

    // Non-alias version:
    MyTemplates::object_up uniqueClass2 = MyTemplates::createFromString<DerivedClass1>("creation info for class 1");
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading