auto can create instances of private classes



  • This really surprised me:

    #include <QCoreApplication>
    #include <QDebug>
    #include <QString>
    #include <cmath>
    
    template<class T>
    class TestIndices
    {
    private:
        class InterOp
        {
        public:
            InterOp()=delete;
            //InterOp(InterOp&)=delete; // prevents copy constructor, we need it
            InterOp(TestIndices& obj, int index)
                :m_obj(obj),
                 m_index(index)
            {}
    
            operator T(){
                return m_obj.getValue(m_index);
            }
    
            InterOp& operator=(T const& value)
            {
                m_obj.setValue(m_index, value);
                return *this;
            }
    
        private:        
            TestIndices& m_obj;
            int m_index;
        };
    
    public:
        TestIndices(){}
    
    //    T const& operator[](int index) const
    //    {
    //        qInfo() << "Reading value: " << index << m_data[index];
    //        return m_data[index];
    //    }
        InterOp operator[](int index){
            qInfo() << "Create interop: " << index;
            return InterOp(*this, index);
        }
    
    private:
        void setValue(int index, T const& value){
            qInfo() << "Writing value: " << index << value;
            m_data[index] = value;
        }
        T getValue(int index){
            qInfo() << "Reading value: " << index << m_data[index];
            return m_data[index];
        }
    
    //private:
    public:
        QVector<T> m_data;
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        
        TestIndices<double> tind;
        tind.m_data.append(0.0);
        tind.m_data.append(1.0);
        tind.m_data.append(2.0);
    
        //TestIndices<double>::InterOp test = tind[1];  // cannot declare private variable
        auto test = tind[1];  // but auto can!
        qInfo() << typeid(test).name();  // N11TestIndicesIdE7InterOpE
        qInfo() << "a" << test;
        test = 3.0;
        qInfo() << "b" << test;
        auto test2 = tind[1];
        qInfo() << "c" << test2;
    
        return a.exec();
    }
    

    Output:

    Create interop:  1
    N11TestIndicesIdE7InterOpE
    Reading value:  1 1
    a 1
    Writing value:  1 3
    Reading value:  1 3
    b 3
    Create interop:  1
    Reading value:  1 3
    c 3
    

    Apparently I cannot explicitly declare an instance of the private class, but "auto" can. I wonder if this is a potential problem or just a nice feature. This is C++ 11 btw.

    Edit: Apparently it surprised other people too.



  • This feature allows to return values of "hidden" type from library which can be used only with auto or passed as an argument to some other library function.

    For example, standard library of C++17 introduces a concept of node handle, type of which is left as implementation detail and may be different between implementations or their versions. You can do a few operations with node handles, but cannot ever reference their "true" type.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.