Why won't it compile in VS Express 2013 even though it compiles in MinGW?
Here's a compiled sample that I stitched together from multiple header files. The code won't make sense because I have gutted all the nonessential parts, but the bottom line is that I am implementing Scott Meier's proxy technique (mentioned here ), even though it turned into more wrappers than a temporary proxy. None of this matters, although my question appears to be purely a difference in compiler behavior.
#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 to Ideone and also via Jetbrain CLion (Toolchain: MinGW 3.20, CMake 2.8.12.2):
However, it won't compile on VS Express 2013:
Running the complete code from CLion (which includes 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 broadcast operator
operator const T& () const
{
if ( _state != State::SET )
{
std::cout << "EXCEPTION" << std::endl;
// TODO throw exception
}
return _data;
}
should convert Proxy<T>
to T
, i.e. Proxy<double>
in double
. And when I forcibly drop the offensive line
sum += (double)input[-j];
it works great. Any ideas?
source to share
This seems to break the MSVC pattern more. It refuses to instantiate Proxy<double>
in this code, which causes the overload resolution to fail. Just adding Proxy<double> p;
right before the definition CRIXUS_MA
that forces implicit creation is enough to make the code compile. According to §14.7.1 [temp.inst] / p6:
Class template specialization is implicitly created if the class type is used in a context that requires a fully-qualified object type, or if the completeness of the class type might affect the semantics of the program. [Note: in particular, if the semantics of an expression depends on a list of elements or the base class of a class template specialization, the class template specialization is implicitly generated. For example, removing a pointer to a class type depends on whether the class declares a destructor or not, and the conversion between pointers and class types depends on the inheritance of the relationship between the two participating classes. -end note]
Since semantics sum += input[-j];
are obviously definition dependent Proxy<double>
, they had to be implicitly instantiated.
source to share