Reputation: 697
Is it possible in C++ to create custom method which will work as overloaded operator? For example simple class:
class A
{
public:
A(int val){ x = val;}
int getInt(){ return (x + 2); }
private:
int x;
};
How to do method toSpecialString
which will, for example, format my returned int
in a special way and then return this string
(e.g "abc14"). Example:
A a(12);
std::cout << a.getInt().toSpecialString() << std::endl;
As output I'm expecting "abc14". Is something like that possible in C++?
Upvotes: 2
Views: 61
Reputation: 11550
Sure, for example
class A
{
struct ReturnedInt {
int x;
// constructor
ReturnedInt(int x_) : x(x_) { }
// "transparent" type cast to int
operator int() { return x; }
std::string toSpecialString() {
std::ostringstream oss{};
oss << "abc" << x;
return oss.str();
}
};
public:
A(int val){ x = val;}
ReturnedInt getInt(){ return (x + 2); } // I changed the return type but see the remarks below
private:
int x;
};
Then
int main () {
A a{12};
std::cout << a.getInt() << '\n';
std::cout << a.getInt().toSpecialString() << '\n';
}
prints
14
abc14
where the former was passed to the cout
's operator<<
as a plain int
(decaying automatically) but in the latter we use the fact that the return value is actually an object. For the same reason as the former line, any function expecting an int
will also accept ReturnedInt
. Moreover, in the compiled binary this kind of "wrapper" structure should come at zero additional cost.
Note that the inner class can be private (like in my example) if you don't intend to expose it for any other purposes. This does not collide with the fact that it's used as a return type or that its (public) methods are invoked.
Upvotes: 3
Reputation: 206557
a.getInt().toSpecialString()
does not work since a.getInt()
returns an int
. An int
is not a class and hence, cannot have a member function.
Possible solutions:
Add toSpecialString()
as a member function.
class A
{
...
std::string toSpecialString()
{
return std::string("abc") + std::to_string(getInt());
}
};
and use it as:
a.toSpecialString();
Add another class to create a string.
struct MyStringFormatter
{
std::string toSpecialString(int x)
{
return std::string("abc") + std::to_string(x);
}
};
and use it as:
MyStringFormatter().toSpecialString(a.getInt());
If necessary, MyStringFormatter
can be updated to take an instance of A
and return the string.
struct MyStringFormatter
{
std::string toSpecialString(A a)
{
return toSpecialString(a.getInt());
}
std::string toSpecialString(int x)
{
return std::string("abc") + std::to_string(x);
}
};
and can be used as:
MyStringFormatter().toSpecialString(a);
My recommendation would be to use the second method. It separates class A
from the special logic used to format an int
.
Upvotes: 1