我想在向量中访问类型擦除类型的getter. getter标记为const.不知何故,const-ness不会传播到boost :: any包装器对象.最小的例子
#include <iostream> #include <vector> #include <boost/mpl/vector.hpp> #include <boost/type_erasure/any.hpp> #include <boost/type_erasure/member.hpp> using namespace boost; using namespace boost::type_erasure; BOOST_TYPE_ERASURE_MEMBER((has_test),test,1) using AnyTest = any<mpl::vector<copy_constructible<>,has_test<int(double)>,relaxed>>; struct ATest { int test(double x) const { return 5; } }; int main() { auto xs = std::vector<AnyTest>{}; xs.push_back(ATest{}); for (const auto& x : xs) { std::cout << x.test(42.0) << '\n'; } }
导致错误说
clang++ -O3 -std=c++14 minimal.cc -o minimal minimal.cc:28:18: error: member function 'test' not viable: 'this' argument has type 'const boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>,has_test<int (double),boost::type_erasure::_self>,boost::type_erasure::relaxed,mpl_::na,mpl_::na>,boost::type_erasure::_self>',but function is not marked const std::cout << x.test(42.0) << '\n'; ^ minimal.cc:11:39: note: 'test' declared here BOOST_TYPE_ERASURE_MEMBER((has_test),1) ^ /opt/local/include/boost/type_erasure/member.hpp:133:9: note: expanded from macro 'BOOST_TYPE_ERASURE_MEMBER' member,\ ^ /opt/local/include/boost/type_erasure/member.hpp:242:64: note: expanded from macro 'BOOST_TYPE_ERASURE_MEMBER_I' BOOST_TYPE_ERASURE_MEMBER_II(namespace_name,concept_name,member,N) ^ /opt/local/include/boost/type_erasure/member.hpp:170:44: note: expanded from macro 'BOOST_TYPE_ERASURE_MEMBER_II' typename rebind_any<Base,R>::type member( \ ^ 1 error generated. make: *** [minimal] Error 1
但是,一旦const auto& for循环中的x更改为auto& x,它有效.这是什么原因以及如何要求包装器对象遵循constness?
解决方法
您需要在概念中指定const-ness,如下所示:
using AnyTest = any<mpl::vector< copy_constructible<>,has_test<int(double),const _self>,relaxed> >;
在文档page “Basic Usage”上找到
// https://stackoverflow.com/questions/32743594/boost-type-erasure-any-with-const-member-function #include <iostream> #include <vector> #include <boost/mpl/vector.hpp> #include <boost/type_erasure/any.hpp> #include <boost/type_erasure/member.hpp> using namespace boost; using namespace boost::type_erasure; BOOST_TYPE_ERASURE_MEMBER((has_test),1) using AnyTest = any<mpl::vector< copy_constructible<>,relaxed> >; struct ATest { int test(double) const { return 5; } }; int main() { auto xs = std::vector<AnyTest>{}; xs.push_back(ATest{}); for (auto const &x : xs) { std::cout << x.test(42.0) << '\n'; } }
打印
5