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();
문제
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
해결책
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();
다른 팁
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.