0

So I was writing a an object container for my template class and I keep getting C2672 and C2893 errors on my VS2019. The implemetation are as follows:

template<typename numtype>
    class matrixobjectprofile : public typestream<typestream<matrixobject<numtype> > > {
    public:
        using celltype = matrixobject<numtype>;
        using celliter = celltype*;
        using cellref = celltype&;

        matrixobjectprofile();
        matrixobjectprofile(size_t length, size_t width);
        ~matrixobjectprofile() {}
    private:
        // nothing here...
    protected:
        // nothing here...
    }; 

Where typestream is a subclass of std::vector as such:

template<typename type, typename alloc = std::allocator<type>>
    class typestream : public std::vector<type, alloc> {
    public:
        using type_iterator = type*;

        // copy of all `std::vector`'s constructors as of C++17
        typestream() noexcept(noexcept(alloc()));
        typestream(size_t sz, const type& value = type(), const alloc& allocator = alloc());
        explicit typestream(size_t sz, const alloc& allocator = alloc());
        typestream(const typestream& stream);
        typestream(const typestream& stream, const alloc& allocator);
        typestream(typestream&& stream) noexcept;
        typestream(typestream&& stream, const alloc& allocator);
        typestream(std::initializer_list<type> list, const alloc& allocator = alloc());
        ~typestream() {}

        // some few functionalities added in
        std::vector<type, alloc> vect();
        void sort();
        typestream<type, alloc>& sorted();
        void qsort();
        typestream<type, alloc>& qsorted();
        void copy(typestream<type> setobject);

        virtual bool in_stream(type obj);
        virtual bool fin_stream(type obj);

        typestream operator+ (typestream stream);
        typestream operator- (typestream stream);

        void operator+= (typestream stream);
        void operator-= (typestream stream);
    };

and the object type is a template class:

template<typename numtype>
    class matrixobject {
    public:
        using numiterator = numtype*;
        using objecttype = matrixobject<numtype>;
        using objectref = objecttype&;
        using objectiter = objecttype*;

        matrixobject();
        explicit matrixobject(numtype other);
        ~matrixobject() {};

        void randomize(numtype delim = std::numeric_limits<numtype>::max());
        void maximize();
        void minimize();
        static numtype upper_limit();
        static numtype lower_limit();

        static matrixobject<numtype> generate_random(numtype delim = std::numeric_limits<numtype>::max());

        numtype integral();
        numtype operator() () {
            return (this->_internal);
        }
        explicit operator numtype() {
            return (this->_internal);
        }

        objectref operator= (objecttype other) {
            this->_internal = other._internal;
            return *this;
        }

        objectref operator= (numtype other) {
            this->_internal = other;
            return *this;
        }

        // suppose these are properly implemented
        bool operator== (const objectref other) const;
        bool operator!= (const objectref other) const;
        bool operator>= (const objectref other) const;
        bool operator<= (const objectref other) const;
        bool operator> (const objectref other) const;
        bool operator< (const objectref other) const;

        objectref operator+ (objectref other);
        objectref operator- (objectref other);
        objectref operator* (objectref other);
        objectref operator/ (objectref other);
        objectref operator+= (objectref other);
        objectref operator-= (objectref other);
        objectref operator*= (objectref other);
        objectref operator/= (objectref other);
        objectref operator++ ();
        objectref operator-- ();
    private:
        numtype _internal 
    protected:
        void test_numtype();
        void test_limit(numtype delim);
        void test_limit(double result, double delim);
    };

I implemented the object matrixprofile as:

template<typename numtype>
inline matrixobjectprofile<numtype>::matrixobject(size_t length, size_t width)
    : typestream<typestream<matrixobject<numtype> > >(width, typestream<matrixobject<numtype> >(length))
{}
// invokes constructor std::vector<type, alloc>(size_t sz, const type& value = type(), alloc& allocator = alloc());

I tested the following lines on a seperate file in main():

typestream<typestream<int> > intstream(200, typestream(200, int())); // works
typestream<typestream<matrixobject<int> > > objstream(200, typestream(200, matrixobject<int>())); // C2672 and C2893

*note: * I tested these lines on separate occassion and found only the second line (the one with the template class) causes the errors

What I found more odd is that the header file (contains the implementations) compiles successfully and the error (as researched) can be caused by the absence of boolean comparison operators.

The error on my list is as follows:

Error   C2893   Failed to specialize function template 'unknown-type std::equal_to<void>::operator ()(_Ty1 &&,_Ty2 &&) noexcept(<expr>) const'  
Error   C2672   'operator __surrogate_func': no matching overloaded function found  

and the whole build log:

1>------ Build started: Project: MatrixEngineMaster, Configuration: Debug x64 ------
1>MatrixEngineCore.cxx
1>MatrixEngineMaster.vcxproj -> H:\Git\MatrixEngine\out\lib\Debugx64\MatrixEngineMaster.lib
2>------ Build started: Project: MatrixEngine, Configuration: Debug x64 ------
2>MatrixEngine.cxx
2>E:\Program Files\Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\xutility(4256,18): error C2672: 'operator __surrogate_func': no matching overloaded function found
2>E:\Program Files\Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\xutility(4333): message : see reference to function template instantiation 'bool std::equal<_InIt1,_InIt2,std::equal_to<void>>(const _InIt1,const _InIt1,const _InIt2,_Pr)' being compiled
2>        with
2>        [
2>            _InIt1=const matrixengine::matrixobject<matrixengine::ui08t> *,
2>            _InIt2=const matrixengine::matrixobject<matrixengine::ui08t> *,
2>            _Pr=std::equal_to<void>
2>        ]
2>E:\Program Files\Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\vector(1766): message : see reference to function template instantiation 'bool std::equal<const matrixengine::matrixobject<matrixengine::ui08t>*,const matrixengine::matrixobject<matrixengine::ui08t>*>(const _InIt1,const _InIt1,const _InIt2)' being compiled
2>        with
2>        [
2>            _InIt1=const matrixengine::matrixobject<matrixengine::ui08t> *,
2>            _InIt2=const matrixengine::matrixobject<matrixengine::ui08t> *
2>        ]
2>H:\Git\MatrixEngine\source\MatrixEngineMaster\MatrixEngineSys.hpp(317): message : see reference to function template instantiation 'bool std::operator ==<type,alloc>(const std::vector<type,alloc> &,const std::vector<type,alloc> &)' being compiled
2>        with
2>        [
2>            type=matrixengine::ui08o,
2>            alloc=std::allocator<matrixengine::ui08o>
2>        ]
2>H:\Git\MatrixEngine\source\MatrixEngineMaster\MatrixEngineSys.hpp(315): message : while compiling class template member function 'bool matrixengine::typestream<matrixengine::typestream<matrixengine::ui08o,std::allocator<type>>,std::allocator<matrixengine::typestream<type,std::allocator<type>>>>::in_stream(matrixengine::typestream<type,std::allocator<type>>)'
2>        with
2>        [
2>            type=matrixengine::ui08o
2>        ]
2>H:\Git\MatrixEngine\source\MatrixEngine\MatrixEngine.cxx(68): message : see reference to class template instantiation 'matrixengine::typestream<matrixengine::typestream<matrixengine::ui08o,std::allocator<type>>,std::allocator<matrixengine::typestream<type,std::allocator<type>>>>' being compiled
2>        with
2>        [
2>            type=matrixengine::ui08o
2>        ]
2>E:\Program Files\Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\xutility(4256,1): error C2893: Failed to specialize function template 'unknown-type std::equal_to<void>::operator ()(_Ty1 &&,_Ty2 &&) noexcept(<expr>) const'
2>E:\Program Files\Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\xstddef(200): message : see declaration of 'std::equal_to<void>::operator ()'
2>E:\Program Files\Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\xutility(4256,1): message : With the following template arguments:
2>E:\Program Files\Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\xutility(4256,1): message : '_Ty1=const matrixengine::matrixobject<matrixengine::ui08t> &'
2>E:\Program Files\Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\xutility(4256,1): message : '_Ty2=const matrixengine::matrixobject<matrixengine::ui08t> &'
2>Done building project "MatrixEngine.vcxproj" -- FAILED.
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

do note the alias: using ui08t = unsigned char;

Can anybody help me fix this?

  • Maybe unrelated to your issue, but I suggest you don't inherit from STL containers. Perhaps you could redesign the code to use composition instead. – cigien May 14 '20 at 13:25
  • can you elaborate why? I mean, it would be a lot of overhaul in my code, but would try it, if it would work... – Silverous Black May 14 '20 at 13:41
  • See [this](https://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from-stdvector) question, and [this](https://quuxplusone.github.io/blog/2018/12/11/dont-inherit-from-std-types/) blog post, for starters. – cigien May 14 '20 at 13:44
  • 1
    I see, thanks man, I think I'll do the private inheritance to ease the whole problem of rebuilding `std::vector`'s interface. – Silverous Black May 14 '20 at 14:31

0 Answers0