Question

I would like to make a class with several constructors of the same type. As this is not directly possible, is there a simple way to define readable "dummy" types such as the class could look like:

class Myclass
{
    MyClass(Orange, std::string & name, float size);
    MyClass(Apple, std::string & name, float size);
    MyClass(Banana, std::string & name, float size);
}

I could define Orange, Apple and Banana as struct typedefs, but is there a more convenient way?

Thanks

Was it helpful?

Solution

The standard library does this in various places actually, for example std::piecewise_construct_t. Their standard is to provide...

struct something_t {};

constexpr something_t something = something_t();

OTHER TIPS

Yes you can tag dispatch to overload the constructor arbitrarily:

struct Orange{};
struct Apple{};
struct Banana{};

class MyClass
{
    MyClass(Orange, std::string & name, float size){}
    MyClass(Apple, std::string & name, float size){}
    MyClass(Banana, std::string & name, float size){}
};

int main()
{
    std::string name("Fred");   
    MyClass myObject(Orange(), name, 10.0f);

    return 0;
}

How about using a template parameter?

struct Orange {};
class MyClass
{
public:
    template<typename CT>
    MyClass(CT, std::string & name, float size);
};

template<>
MyClass::MyClass<Orange>(Orange, std::string & name, float size)
{
    // The orange case
}

Which could be used as:

int main()
{
    std::string name("Fred");
    MyClass myObject(Orange(), name, 12.0f);
    return 0;
}

In the above form it is just a more complex route to the tag dispatch approach.
The advantage comes in that you can add extra details into template parameter and make a generic constructor based on them:

struct Orange { static const int pips = 7; };
struct Banana { static const int pips = 1; };

class MyClass
{
    int pips;
public:
    enum ConstructorType {Orange, Apple, Banana};
    template<typename CT>
    MyClass(CT, std::string & name, float size);
};

template<typename CT>
MyClass::MyClass(CT, std::string & name, float size)
: pips(CT::pips)
{

}

You can use the Named constructor idiom. Basically, you create static methods with different names which return new objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top