Help with constness and output operator<<
Dear all,
Suppose you have a class, say "foobar", which let you store elements
in an array of predefined size, such that:
* only elements at even position are assignable [i.e., foo(i) = value
if (i % 2 == 0)]
* elements at odd position are set automatically to zero [i.e., foo(i)
= 0 if (i % 2 == 0)]
To do this I have two methods of foobar:
--- [snip] ---
template <typename T>
class foobar
{
....
reference operator()(std::size_t i)
{
if (!(i % 2))
{
return v_[i];
}
throw std::runtime_error("Not assignable");
}
const_reference operator()(std::size_t i) const
{
if (!(i % 2))
{
return v_[i];
}
return zero_; // The constant 0
}
};
--- [/snip] ---
The problem is that the "const" method is not called in the output
operator <<.
In fact when I execute the line:
std::cout << foo(1) << std::endl
Instead of getting zero as output (resulting from the call to the
const method) I get the exception "Not assignable".
To make it to work I have to explicitly cast to type "foobar const&".
Where I am wrong?
[note: just for info, I'm using the GCC compiler 4.4.1 with flags -
Wall -Wextra -pedantic -ansi]
Here below is the entire code:
--- [code] ---
#include <cstddef>
#include <iostream>
#include <stdexcept>
template <typename T>
struct foobar
{
typedef T value_type;
typedef T& reference;
typedef T const& const_reference;
foobar(std::size_t n)
: v_(new value_type[n/2])
{
}
~foobar() { delete[] v_; }
reference operator()(std::size_t i)
{
if (!(i % 2))
{
return v_[i];
}
throw std::runtime_error("Not assignable");
}
const_reference operator()(std::size_t i) const
{
if (!(i % 2))
{
return v_[i];
}
return this->zero_;
}
private: value_type* v_;
private: static const value_type zero_;
};
template <typename T>
const T foobar<T>::zero_ = 0;
int main()
{
const std::size_t N = 5;
foobar<int> foo(N);
std::cout << "Populating..." << std::endl;;
for (std::size_t i=0; i < N; i += 2)
{
foo(i) = i+1;
}
std::cout << "Querying..." << std::endl;;
for (std::size_t i=0; i < N; ++i)
{
std::cout << "foo(" << i << ") ==> " << std::flush;
std::cout << foo(i) << std::endl; // DON'T WORK
//std::cout << (static_cast<foobar<int> const&>(foo))(i) <<
std::endl; // WORK
}
}
--- [/code] ---
Thank you very much for any advice
Best,
-- Marco
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]