c++ - std::make_shared 需要默认构造函数是否有原因?

标签 c++ c++11 shared-ptr default-constructor make-shared

我试图弄清楚这是否是 cereal 的要求或不。

我不断收到类构造函数(默认构造函数)是私有(private)的错误,我将其放在那里是有原因的。

但是,错误的原始行似乎是 std::make_shared,而不是 Cereal ,它需要默认构造函数,但已经是友元类,因此应该可以访问它。

/usr/include/c++/4.7/type_traits: In instantiation of ‘struct std::__is_default_constructible_impl<Concept>’:
/usr/include/c++/4.7/type_traits:116:12:   required from ‘struct std::__and_<std::__not_<std::is_void<Concept> >, std::__is_default_constructible_impl<Concept> >’
/usr/include/c++/4.7/type_traits:682:12:   required from ‘struct std::__is_default_constructible_atom<Concept>’
/usr/include/c++/4.7/type_traits:703:12:   required from ‘struct std::__is_default_constructible_safe<Concept, false>’
/usr/include/c++/4.7/type_traits:709:12:   required from ‘struct std::is_default_constructible<Concept>’
/usr/local/include/cereal/types/polymorphic.hpp:157:5:   required by substitution of ‘template<class Archive, class T> typename std::enable_if<((! std::is_default_constructible<T>::value) && (! has_load_and_allocate<T, Archive>())), bool>::type cereal::polymorphic_detail::serialize_wrapper(Archive&, std::shared_ptr<_Tp2>&, uint32_t) [with Archive = cereal::XMLInputArchive; T = Concept]’
/usr/local/include/cereal/types/polymorphic.hpp:253:5:   [ skipping 16 instantiation contexts ]
/usr/include/c++/4.7/bits/shared_ptr_base.h:525:8:   required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = SemanticGraph<Concept>; _Alloc = std::allocator<SemanticGraph<Concept> >; _Args = {const char (&)[16]}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’
/usr/include/c++/4.7/bits/shared_ptr_base.h:997:35:   required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<SemanticGraph<Concept> >; _Args = {const char (&)[16]}; _Tp = SemanticGraph<Concept>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’
/usr/include/c++/4.7/bits/shared_ptr.h:317:64:   required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<SemanticGraph<Concept> >; _Args = {const char (&)[16]}; _Tp = SemanticGraph<Concept>]’
/usr/include/c++/4.7/bits/shared_ptr.h:599:39:   required from ‘std::shared_ptr<_Tp1> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = SemanticGraph<Concept>; _Alloc = std::allocator<SemanticGraph<Concept> >; _Args = {const char (&)[16]}]’
/usr/include/c++/4.7/bits/shared_ptr.h:615:42:   required from ‘std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = SemanticGraph<Concept>; _Args = {const char (&)[16]}]’
/home/alex/projects/Icarus/trunk/Api/ConnectionHandler/../../Processes/Controller/../../Datatypes/Domain/../../Handlers/SemanticNodeFactory/SemanticNodeFactory.hpp:34:82:   required from here
/home/alex/projects/Icarus/trunk/Api/ConnectionHandler/../../Processes/Controller/../../Datatypes/Domain/../Episode/../State/../ConceptGraph/../Concept/Concept.hpp:27:5: error: ‘Concept::Concept()’ is private

有人可以向我解释为什么会发生这种情况,更重要的是,除了公开这些构造函数之外,如何解决它?

编辑:

原始错误行来自:

concept_map  = std::make_shared<SemanticGraph<Concept>>( "concept_map.xml" );

SemanticGraph Ctor 在哪里:

    SemanticGraph
    (
      const std::string filename
    )
    : 
      _fname ( filename )
    {
      std::ifstream input( _fname );
      if ( input.is_open() )
      {
       cereal::XMLInputArchive archive( input );
       archive( _nodes );
      }
    }

最佳答案

C++ 过去在实例化模板时不考虑访问控制,除非需要时产生错误。您使用的编译器仍然使用这些规则。因此,您的类不被视为不可默认构造。相反,检查本身是不可能的。

GCC 4.8 及更高版本确实支持这一点。一个简单的演示程序,在 4.8 上成功,在 4.7 上失败:

#include <type_traits>

class S { S() {} };

int main() {
  return std::is_default_constructible<S>::value;
}

在 4.8 中,这会返回 0。在 4.7 中,这会产生编译时错误。

要解决此问题,请确保您没有默认构造函数,甚至没有私有(private)构造函数。您可以向构造函数添加一个虚拟参数,并确保始终传递该虚拟参数。

关于c++ - std::make_shared 需要默认构造函数是否有原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19835114/

相关文章:

c++ - 覆盖 [[noreturn]] 虚函数

c++ - 绑定(bind) shared_ptr::reset - 未找到匹配的重载函数

c++ - OpenGl 代码不适用于带有 VS2013 CPP 的 cocos2dx-3.0

c++ - typedef 的 STL 容器类型作为模板参数

c++ - g++优化使程序无法运行

c++ - std::function 和 std::bind 行为

c++ - 使用从另一个具体类返回的 shared_ptr

c++ - 在一组 shared_ptr<QString> 中搜索

c++ - 减少 boost build 中的内存使用

c++ - 如何确保 DirectX 11 应用程序在带有 C++ 的双 GPU 笔记本电脑上使用独立 GPU?