【问题标题】:Error with constructor of private struct inside a class类中私有结构的构造函数出错
【发布时间】:2017-03-10 16:59:35
【问题描述】:

我有这门课:

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&lt;int,int,int&gt; 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),一切正常并且不会发生编译错误。为什么?并且热解决它?

【问题讨论】:

    标签: c++ templates constructor


    【解决方案1】:

    问题似乎在于您缺少CacheElem 的默认构造函数。在代码中的某处,CacheElem 需要默认构造,因为您将其存储在要求元素默认可构造的 STL 容器中,或者因为您只是尝试在不调用构造函数的情况下在某处实例化一个。

    【讨论】:

    • 糟糕,我认为这与 friend 声明的问题相同。
    • @DanielEisener 感谢您的回答,请查看问题底部的新部分。
    【解决方案2】:

    感谢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 构造函数元素,这是非法的。

    【讨论】:

    • 是的,你明白了:vector(size_type N) 构造函数创建了一个带有N 默认构造元素的vector。如果您的value_type 没有默认构造函数,则此构造函数不起作用。不幸的是,没有构造函数来设置容量而不是大小。
    猜你喜欢
    • 2011-04-20
    • 2012-07-22
    • 2013-09-19
    • 2021-09-19
    • 2019-10-16
    相关资源
    最近更新 更多