I want to create an interface for classes that return a message. My problem is that sometimes it will be better to return a string and sometimes a const string&. What would be the best way to give inheriting classes the possibility of choosing the return type?
struct Verbose{
// my message is a class member
virtual const string& getMsg()const=0;
// my message is created in the function
virtual string getMsg()const=0;
};
Instead of this interface, I'd like something like this, so as to offer this flexibility
struct Verbose{
virtual myPrintableType getMsg()const=0;
};
You can use ref-qualifiers for your member functions:
struct Verbose{
virtual const std::string& getMsg() const& = 0;
virtual std::string getMsg() const&& = 0;
};
struct Derived: Verbose {
std::string s{"xxx"};
const std::string& getMsg()const& {
std::cout << "const string&\n";
return s;
}
std::string getMsg()const&& {
std::cout << "string\n";
return "yyy";
}
};
First version will be called only if your object is an l-value, i.e. it's considered safe to return member field by const reference. Second version will be called for r-values.
Derived d;
std::cout << d.getMsg() << std::endl; // calls 1st overload
std::cout << Derived{}.getMsg() << std::endl; // calls 2nd overload
This is assuming that you want to have different behavior depending on value category. If it's not the case and you need different return types for the same value category, then you need 2 different functions.