I've been looking for this for a bit and haven't had any luck. May be that I'm searching for the wrong words, or perhaps it's an unusual request (Or simply not doable).
Regardless, my question: I want to be able to use an instance of a class... well, here's a very simple example:
class attribute
{
float value;
float min;
float max;
}
attribute attr1;
attr1.value = 5.0f;
Now, basically, I want to use attr1 as if I'm calling
attr1.value
So when I, say,
std::cout << attr1 << std::endl;
It would print 5.0 (Or just 5).
Thanks!
You need to implement
std::ostream& operator<<(std::ostream& os, attribute const& att)
{
os << att.value;
return os; // this is how you "chain" `<<`
}
Either permit att.value through public, friendship, or write a function.
Another alternative would be to build a cast operator to float:
class attribute
{
public:
operator float() const
{
return value;
}
private:
/*the rest of your class here*/
But this could introduce unexpected ambiguities.
Finally, if you want attribute to behave like a numeric type, then you can overload more operators as you see fit. For example, to overload +=, you could write
template<typename Y>
attribute& operator+=(const Y& p)
{
value += p;
return *this;
}
Related
I would like to have an int wrapper class that behaves like int without the need to overload all of the operators. The same question was asked but not really answered here. I know I can write a template wrapper and overload dozens of operators to achieve that (in fact, I have it like that now - basically it looks like this mess). However it would be nice if it would be possible to somehow expose the internal primitive type without the need to overload the operators that just forward the call to it.
Is that possible? Perhaps by overloading dereferencing operators or somesuch?
EDIT: Example code:
template<typename T>
class IDWrapper
{
public:
inline IDWrapper() { }
inline IDWrapper(T id) : m_Value(id) { }
constexpr static int size() { return sizeof(T); }
constexpr static T min() { return std::numeric_limits<T>::min(); }
constexpr static T max() { return std::numeric_limits<T>::max(); }
inline bool isValid() const { return m_Value != 0; }
inline operator T() const { return m_Value; }
inline operator T&() { return m_Value; } //this line was the attempt to make it transparent... unsuccessfully
inline IDWrapper &operator=(T v) { m_Value = v; return *this; }
inline void invalidate() { m_Value = 0; }
private:
T m_Value = 0;
};
Basically it wraps an ID of type T in a "special" way so that it gives convenient options for validating and invalidating it. Plus it gives convenient access the the size and min/max. The reason for the templated wrapper is that I will need to replace it later with base64 number or some other non-standard number type and I need the interface that relies on the IDWrapper to stay consistent. The numerical operators will still be provided by T so when I spell them out here I am just forwarding the call hence the question.
So I have fiddled with it inspired by the comments to the OP and it seems that having these two (and only these two) overloaded operators can do the trick:
operator T&() { /*...*/ }
operator const T&() const { /*...*/ }
Naturally it is not without the cost. For example if T is an int (or any type for which sizeof(T) < sizeof(void*)) then returning const reference to it is more expensive than doing a copy (but having a copy operator breaks the transparency). Not to mention memory address lookup. I am not sure about potential other problems with this so feel free to comment/answer. But this works.
Regarding overloading brackets in C++, my compiler is using the mutator method for access. Can anyone tell me why?
1. const int & Cheese::operator [] (int i)const { return weight[i]; } //accessor
2. int & Cheese::operator [] (int i) { return weight[i]; } //mutator
For example, the cout command below is using the mutator function definition--#2 above--to access the data.
Cheese cheddar;
cout << cheddar[2] << endl;
Why is this not using the first function--the accessor--to get the data? I would think that, since the cout is simply a retrieval, it would fire on the first.
How does the compiler know which of these to invoke?
EDIT: For completeness, by mutator, I mean used as a "setter," like so:
cheddar[2] = 100;
Both together would be as follows:
cheddar[2] = cheddar[1];
Where the rhs is just a "getter." It simply retrieves the value of cheddar[1], does not change anything, and thus can be const. In contrast, the lhs bracket overload cheddar[2] functions as a "setter;" the value can be changed, and function return value can't be const.
It invokes the first one for any constant instance (like const Cheese or const Cheese&) and the second one for mutable instances.
In case you care about a way you can get roughly the effect you seem to want (specifically, to have one function executed to get the value, and other code to set the value, dependably), there is a way to do that.
The usual way is to return a proxy instead of returning the value (or a reference to it) directly. The proxy overloads operator T and operator=.
template <class T>
class Proxy {
T value;
public:
Proxy(T v) : value(v) {}
// used only to get value
operator T() const { return value; }
// used only to set value
Proxy &operator=(T new_value) {
value = new_value;
return *this;
}
};
Then your overload just returns an instance of this:
Proxy<Cheese &> operator[](int i) { return Proxy<int>(weight[i]); }
Proxy<Cheese const &> operator[](int i) const { return Proxy<int>(weight[i]); }
Note that in the second case, T has the type Cheese const & and operator= isn't a const member function, so you won't be able to use operator= in this case (which is exactly what you normally want).
I'll describe the question by means of what I'm trying to achieve.
Imagine you have a Parameter class:
class Parameter
{
private:
float _parameter, _parameterScaler;
public:
Parameter()
{
_parameter = 1;
_parameterScaler = 0.5;
}
void SetValue(float value)
{
_parameter = value;
}
void SetValueOffset(float value)
{
_parameterScaler = value;
}
float "use of variable of this class"
{
return _parameter * _parameterScaler;
}
}
This class holds two floats, one of which is parameter value, and another is parameter multiplier.
Now if I use the variable of type Parameter as follows:
int main()
{
Parameter param;
param.SetValue(5);
param.SetValueOffset(0.5);
printf("%6.2f", param);
}
It prints: 2.5.
I could achieve such an effect with operator overloading using () for example. Is it possible just with variable usage?
No it is not, because printf doesn't do anything to the parameters - doesn't apply casts or conversions and is oblivious to their types.
What you can do is use std::cout instead and overload ostream& operator << (ostream& str, const Parameter&), that way
std::cout << param;
will print exactly what you want it to print.
The code printf("%6.2f", param); just treats param as if it were a float without doing any casting (and is overall bad). Don't do it!
I was implementing (for training purpose) a Bubble Sort template function:
template<typename iterInput,
typename predicate>
void BubbleSort(iterInput first1,iterInput last1,predicate func)
{
bool swapped(false);
do
{
swapped = false;
iterInput begin = first1;
iterInput beginMinus = first1;
++begin;
for (;begin != last1; begin++,beginMinus++)
{
if (func(*beginMinus,*begin) )
{
std::swap(*beginMinus,*begin);
swapped = true;
}
}
}
while(swapped);
}
When I have realized that this function will not work for class with no assignment operator, like this one (forgive me for the bad name):
class NoCopyable
{
public:
explicit NoCopyable(int value) : value_(value) {}
NoCopyable(const NoCopyable& other) : value_(other.value_) {}
~NoCopyable() {}
bool operator<(const NoCopyable& other) { return value_ < other.value_; }
void setValue(int value) { value_ = value; }
std::ostream& print(std::ostream& os) const { return os << value_; }
private:
NoCopyable& operator=(const NoCopyable& other);
int value_;
};
std::ostream& operator<<(std::ostream& os, const NoCopyable& obj)
{
return obj.print(os);
}
struct PrintNoCopyable
{
void operator()(const NoCopyable& noCopyable) { std::cout << noCopyable << '\n'; }
};
The compiler raises this error Error 1 error C2248: 'NoCopyable::operator =' : cannot access private member declared in class 'NoCopyable'
So, I have slightly modify the code using instead of the std::swap function my version of the swap function, here is the code:
template<typename T1,
typename T2>
void noAssignmentSwap(T1& t1,T2& t2)
{
T1 temp(t1);
t1.~T1();
new (&t1) T1(t2);
t2.~T2();
new (&t2) T2(temp);
}
The code compiles and gives the right result. However I am not completely sure, I remember a Sutter's article that suggest you to avoid playing with the objects life time. The article just warns you by playing with fire without actually giving you any real reason. I can see problem in exception safety if the copy constructor of T1 or T2 can throw. However there is the same problem in the standard version if the assignment operator is allowed to throw.
Here the question, can you see any possible drawbacks in this version of swap?
Cheers
Apart from anything else, if a class does not have an assignment operator, its designer probably did not intend it to be swapped. If they did that, they probably disabled copy construction too, so your new swap function still won't work.
As for your assertion that Standard Library containers do not need assignment - that is true so long as you don't want to actually do anything useful with them. Does this code compile for you?
#include <vector>
using namespace std;
struct A {
private:
void operator=( const A &);
};
int main() {
vector <A> v;
v.push_back( A() );
v[0] = A(); // assignment needed here
}
I think it won't.
The difference is that when the assignment operator fails, you still have the same number of objects.
If you destroy one object and fail to create a new one, one object is lost! If it was part of a container, the container's state is probably also invalid.
You need a copy ctor instead of an assignment operator, but the two are sufficiently similar that at least in a typical case, you'll have both or you'll have neither. IOW, I don't think this generally accomplishes much.
I'd class it right along side the xor-swap trick: interesting, but generally useless.
It might be confusing to a future maintainer of the code.
There is the complex<> template in C++ standard library, and it has an overloaded << operator so that it outputs complex numbers in the (real_part, im_part) format. I need to change the behavior of that operator for complex numbers so that the output format is changed to something completely different. Specifically, I need the output to be in the form real_part\tim_part. How do I do that?
There's no direct way to replace operator <<, but you do have a few options. First, you could just write your own function to print complex numbers:
template <typename T> void PrintComplex(const complex<T>& c) {
/* ... */
}
If you want to still use the nice stream syntax, then one trick you could do would be to make a wrapper class that wraps a complex and then defines its own operator << that prints it out in a different way. For example:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
complex<T> c;
};
Once you have this, you could write something like
cout << ComplexPrinter<double>(myComplex) << endl;
You can make this even cleaner by writing a function like this one to wrap the object for you:
template <typename T>
ComplexPrinter<T> wrap(const complex<T>& c) {
return ComplexPrinter<T>(c);
}
This then lets you write
cout << wrap(myComplex) << endl;
Which isn't perfect, but is pretty good.
One thing to note about the above wrapper is that it has an implicit conversion constructor set up to let you convert complex<T>s to ComplexPrinter<T>s. This means that if you have a vector< complex<T> >, you can print it out using your custom code by calling
vector< complex<double> > v = /* ... */
copy (v.begin(), v.end(), ostream_iterator< ComplexPrinter<double> >(cout, " "));
On output, the implicit conversion constructor will transform your complex<double>s into the wrappers, and your custom code will do the printing for you.
If you want to be very adventurous and cast caution to the wind, you could even write the class so that it just stores a reference to the original complex, as shown here:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
const complex<T>& c;
};
This completely eliminates any copying and just makes the wrapper a thin veneer around a real complex. (No pun intended). You'd have to be very careful if you did this not to pass these objects around across scope boundaries where the original objects go out of scope, but if it's what you want it might work out just great.
Hope this helps!
template<class T>
struct my_complex_format_type {
std::complex<T> const &x;
my_complex_format_type(std::complex<T> const &x) : x (x) {}
friend std::ostream& operator<<(std::ostream &out,
my_complex_format_type const &value)
{
out << "format value.x however you like";
return out;
}
};
template<class T>
my_complex_format_type<T> my_complex_format(std::complex<T> const &x) {
return x;
}
void example() {
std::cout << my_complex_format(some_complex);
}
For any specific instantiation of complex<T>, Use a strong typedef (boost has a version) and cast to that type during << calls. Override << for that type.
If you need to override << for any variation of complex<T> then life will be harder.
My answer to the same question here: c++ display complex number with i in imaginary part produces the behavior you want, at the expense of some risk of future incompatibility because it inserts a template specialization into the std:: namespace.
There is no really tidy way to do that. My suggestion would be to just ditch iostreams and write something more C-like instead. It will probably be faster to write, faster to read and faster to execute.