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):

enter image description here

However, it won't compile on VS Express 2013:

enter image description here

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?

+3


source to share


1 answer


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.

+4


source







All Articles