Here's a compilable sample I stitched together from several header files. The code won't make sense because I gutted all the irrelevant parts, but the gist is that I'm implementing Scott Meyers' data proxy technique (mentioned here), though it's evolved into more of a wrapper than a temporary proxy. None of that should matter though—my question seems to be purely regarding a difference in compiler behaviors.
#include <iostream>
#include <vector>
template<typename T>
class Proxy
{
public:
enum class State
{
NEVER_SET = 0,
SET,
UNSET
};
operator const T& () const
{
if ( _state != State::SET )
{
std::cout << "EXCEPTION" << std::endl;
// TODO throw exception
}
return _data;
}
Proxy<T>& operator=(const T& val)
{
_data = val;
_state = State::SET;
return (*this);
}
Proxy<T>& operator+=(const T& val)
{
_data = (*this) + val;
_state = State::SET;
return (*this);
}
private:
T _data;
State _state = State::NEVER_SET;
};
class Tape
{
};
template<typename T>
class tape : public Tape
{
public:
const Proxy<T>& operator[](int idx) const
{
return operator[](idx);
}
Proxy<T>& operator[](int idx)
{
if ( idx >= data.size() )
{
data.resize(idx + 1);
}
return data[idx];
}
private:
std::vector< Proxy<T> > data;
};
class CRIXUS
{
public:
virtual void Go() final {};
protected:
virtual void Pre() {};
virtual void Post() {};
virtual void Step() = 0;
};
class CRIXUS_MA : public CRIXUS
{
public:
int window = 30;
tape<double> input;
tape<double> output;
protected:
virtual void Step()
{
double sum = 0;
for ( int j = 0; j < window; j++ )
{
sum += input[-j];
}
output[0] = sum / window;
}
};
int main()
{
}
It compiles fine on Ideone as well as via Jetbrain's CLion (Toolchain: MinGW 3.20, CMake 2.8.12.2):
However it won't compile on VS Express 2013:
Running the full code from CLion (which involves reading a .csv file of numbers and outputting a moving average), I can verify that the output is correct. It's just that VS won't compile the code.
As far as I can tell, the cast operator
operator const T& () const
{
if ( _state != State::SET )
{
std::cout << "EXCEPTION" << std::endl;
// TODO throw exception
}
return _data;
}
should convert the Proxy<T>
to T
, i.e. Proxy<double>
to double
. And when I forcibly cast the offending line,
sum += (double)input[-j];
it works fine. Any ideas?