类中私有结构的构造函数出错

时间:2017-03-10 16:59:36

标签: c++ templates constructor

我有这堂课:

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
    };
...

我用cc::Cache<int,int,int> cache(...)实例化了这个对象(我不知道你是否需要知道所有传递的参数,在这种情况下让我知道),但是我得到了这个我根本不理解的错误:

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

为什么会这样?

更新评论答案:

好的,我发现了问题所在,但为什么却发现了问题。 Cache构造函数实现就是这个:

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) {}

values声明为:

    std::vector<CacheElem> values;

但是如果我从上面的构造函数中删除values(size),一切正常,并且不会发生编译错误。为什么?热点解决了吗?

2 个答案:

答案 0 :(得分:2)

看起来问题是你错过了CacheElem的默认构造函数。在代码的某处,CacheElem需要默认构造,因为你将它存储在一个STL容器中,该容器需要元素是默认构造的,或者因为你只是试图在不调用构造函数的情况下在某处实例化它。

答案 1 :(得分:1)

由于this回答提示,我发现了错误。

从此更改Cache构造函数实现:

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) {}

对此:

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);
}

解决了这个问题。我认为因为调用values(size)隐式调用resize()这是非法的,而不提供CacheElem构造函数元素。

相关问题