justHelloWorld
justHelloWorld

Reputation: 6818

Error with constructor of private struct inside a class

I have this class:

template <typename C, typename R, typename D>
class Cache {

typedef std::shared_ptr<cc::Distance<C,D>> DistancePtr;

public:
    Cache(const DistancePtr distance, const std::function<R(C)> &backEnd, const size_t size = 10000, const float treshold = 0);
...
private:
    struct CacheElem{
        CacheElem(const C code, const R result, std::list<size_t>::iterator listElem) : code(code), result(result), listElem(listElem) {}
        C code;
        R result;
        std::list<size_t>::iterator listElem; //pointing to corresponding element in lru0
    };
...

I instantiated this object with cc::Cache<int,int,int> cache(...) (I don't know if you need to know all passed arguments, let me know in that case), but I get this error that I don't understand at all:

In file included from /usr/include/c++/5/memory:64:0,
                 from ../main.cpp:9:
/usr/include/c++/5/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = cc::Cache<int, int, int>::CacheElem; _Args = {}]’:
/usr/include/c++/5/bits/stl_uninitialized.h:519:18:   required from ‘static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = cc::Cache<int, int, int>::CacheElem*; _Size = long unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/5/bits/stl_uninitialized.h:575:20:   required from ‘_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = cc::Cache<int, int, int>::CacheElem*; _Size = long unsigned int]’
/usr/include/c++/5/bits/stl_uninitialized.h:637:44:   required from ‘_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = cc::Cache<int, int, int>::CacheElem*; _Size = long unsigned int; _Tp = cc::Cache<int, int, int>::CacheElem]’
/usr/include/c++/5/bits/stl_vector.h:1311:36:   required from ‘void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = cc::Cache<int, int, int>::CacheElem; _Alloc = std::allocator<cc::Cache<int, int, int>::CacheElem>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/5/bits/stl_vector.h:279:30:   required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = cc::Cache<int, int, int>::CacheElem; _Alloc = std::allocator<cc::Cache<int, int, int>::CacheElem>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<cc::Cache<int, int, int>::CacheElem>]’
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:59:85:   required from ‘cc::Cache<C, R, D>::Cache(cc::Cache<C, R, D>::DistancePtr, const std::function<R(C)>&, size_t, float) [with C = int; R = int; D = int; cc::Cache<C, R, D>::DistancePtr = std::shared_ptr<cc::Distance<int, int> >; size_t = long unsigned int]’
../main.cpp:33:53:   required from here
/usr/include/c++/5/bits/stl_construct.h:75:7: error: no matching function for call to ‘cc::Cache<int, int, int>::CacheElem::CacheElem()’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^
In file included from ../Core/CCCore.hpp:19:0,
                 from ../main.cpp:15:
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:36:4: note: candidate: cc::Cache<C, R, D>::CacheElem::CacheElem(C, R, std::__cxx11::list<long unsigned int>::iterator) [with C = int; R = int; D = int; std::__cxx11::list<long unsigned int>::iterator = std::_List_iterator<long unsigned int>]
    CacheElem(const C code, const R result, std::list<size_t>::iterator listElem) : code(code), result(result), listElem(listElem) {}
    ^
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:36:4: note:   candidate expects 3 arguments, 0 provided
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:35:10: note: candidate: constexpr cc::Cache<int, int, int>::CacheElem::CacheElem(const cc::Cache<int, int, int>::CacheElem&)
   struct CacheElem{
          ^
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:35:10: note:   candidate expects 1 argument, 0 provided
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:35:10: note: candidate: constexpr cc::Cache<int, int, int>::CacheElem::CacheElem(cc::Cache<int, int, int>::CacheElem&&)
/home/luca/Dropbox/HKUST/CloudCache/cloudcache/CloudCache/Core/Cache.hpp:35:10: note:   candidate expects 1 argument, 0 provided
<builtin>: recipe for target 'main.o' failed
make: *** [main.o] Error 1

Why this happen?

UPDATE TO COMMENT ONE ANSWER:

Ok I found out where the problem is, but not why it occours. The Cache constructor implementation is this one:

template <typename C, typename R, typename D>
Cache<C,R,D>::Cache(const DistancePtr distance, const std::function<R(C)> &backEnd, const size_t size, const float treshold)
: distance(distance), backEnd(backEnd), values(size), treshold(treshold), size(size) {}

Where values is declared as:

    std::vector<CacheElem> values;

But if I delete values(size) from the constructor above, everything works fine and no compile error occurs. Why? And hot to solve it?

Upvotes: 1

Views: 100

Answers (2)

justHelloWorld
justHelloWorld

Reputation: 6818

I found the error thanks to the tip from this answer.

Changing the Cache constructor implementation from this:

template <typename C, typename R, typename D>
Cache<C,R,D>::Cache(const DistancePtr distance, const std::function<R(C)> &backEnd, const size_t size, const float treshold)
: distance(distance), backEnd(backEnd), values(size), treshold(treshold), size(size) {}

To this:

template <typename C, typename R, typename D>
Cache<C,R,D>::Cache(const DistancePtr distance, const std::function<R(C)> &backEnd, const size_t size, const float treshold)
: distance(distance), backEnd(backEnd), treshold(treshold), size(size) {
    values.reserve(size);
}

Solved the problem. I think because calling values(size) is implicitly calling resize() which is illegal without providing CacheElem constructor elements.

Upvotes: 1

Daniel Eisener
Daniel Eisener

Reputation: 333

It looks like the problem is that you're missing a default constructor for CacheElem. Somewhere in your code, a CacheElem needs to be default constructed, either because you stored it in an STL container that requires elements to be default constructible, or because you simply tried to instantiate one somewhere without calling a constructor.

Upvotes: 2

Related Questions