使用Boost.TypeErasure模拟纯虚模板成员函数编译报错求助
问题描述
参考Boost.TypeErasure文档中的“polymorphic range formatter”示例(可模拟纯虚模板成员函数),尝试简化实现一个仅接收值并输出到std::cout的示例,编写代码如下:
#include <boost/type_erasure/any.hpp> #include <boost/type_erasure/iterator.hpp> #include <boost/type_erasure/operators.hpp> #include <boost/type_erasure/tuple.hpp> #include <boost/type_erasure/same_type.hpp> #include <iostream> using namespace boost::type_erasure; struct _x : placeholder {}; class abstract_printer2 { public: template<class X> void print(X x) const { tuple<requirements, _x> args(x); do_print(get<0>(args)); } virtual ~abstract_printer2() {} protected: typedef boost::mpl::vector< ostreamable<std::ostream, _x> > requirements; typedef boost::type_erasure::any<requirements, _x> x_type; virtual void do_print(x_type x) const = 0; }; class separator_printer2 : public abstract_printer2 { protected: virtual void do_print(x_type x) const { std::cout << x << std::endl; } }; int main() { separator_printer2 p4; int q = 5; p4.print(q); }
编译错误信息
在Visual Studio 2022中编译时出现以下错误:
Build started at 14:02... 1>------ Build started: Project: test, Configuration: Debug x64 ------ 1>test.cpp 1>C:\bob\projects\test\test.cpp(17,17): error C2280: 'boost::type_erasure::any<abstract_printer2::requirements,_x>::any(const boost::type_erasure::any<abstract_printer2::requirements,_x> &)': attempting to reference a deleted function 1>C:\bob\projects\boost\boost\type_erasure\any.hpp(1928,1): 1>compiler has generated 'boost::type_erasure::any<abstract_printer2::requirements,_x>::any' here 1>C:\bob\projects\boost\boost\type_erasure\any.hpp(1928,1): 1>'boost::type_erasure::any<abstract_printer2::requirements,_x>::any(const boost::type_erasure::any<abstract_printer2::requirements,_x> &)': function was implicitly deleted because a base class invokes a deleted or inaccessible function 'boost::type_erasure::any_constructor_control<boost::type_erasure::any_constructor_impl<Concept,T>,void>::any_constructor_control(const boost::type_erasure::any_constructor_control<boost::type_erasure::any_constructor_impl<Concept,T>,void> &)' 1> with 1> [ 1> Concept=abstract_printer2::requirements, 1> T=_x 1> ] 1>C:\bob\projects\boost\boost\type_erasure\any.hpp(376,5): 1>'boost::type_erasure::any_constructor_control<boost::type_erasure::any_constructor_impl<Concept,T>,void>::any_constructor_control(const boost::type_erasure::any_constructor_control<boost::type_erasure::any_constructor_impl<Concept,T>,void> &)': function was explicitly deleted 1> with 1> [ 1> Concept=abstract_printer2::requirements, 1> T=_x 1> ] 1>C:\bob\projects\test\test.cpp(17,17): 1>the template instantiation context (the oldest one first) is 1> C:\bob\projects\test\test.06.factory\test.cpp(38,7): 1> see reference to function template instantiation 'void abstract_printer2::print<int>(X) const' being compiled 1> with 1> [ 1> X=int 1> ] 1>Done building project "test.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== ========== Build completed at 14:02 and took 01.517 seconds ==========
问题原因与修复方案
错误核心是boost::type_erasure::any的拷贝构造函数被删除,原因如下:
- 定义
x_type时的requirements仅包含ostreamable<std::ostream, _x>,未添加copy_constructible<_x>约束,导致any默认禁用拷贝构造。 do_print函数的参数是x_type x(值传递),调用时需要拷贝构造any对象,触发了被删除的拷贝构造函数。
有两种修复方式:
方式一:添加拷贝构造约束
在requirements中加入copy_constructible<_x>:
typedef boost::mpl::vector< ostreamable<std::ostream, _x>, copy_constructible<_x> // 添加拷贝构造约束 > requirements;
方式二:改用引用传递参数
将do_print的参数改为const x_type&,避免拷贝操作:
// abstract_printer2中修改函数声明 virtual void do_print(const x_type& x) const = 0; // separator_printer2中修改函数实现 virtual void do_print(const x_type& x) const { std::cout << x << std::endl; }
两种方式任选其一即可解决编译错误,推荐方式二,无需额外添加拷贝约束,同时避免不必要的对象拷贝。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

