В последнее время я пытаюсь использовать boost.type_erasure с заранее объявленным типом, как показано ниже:
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/member.hpp>
struct Type;
BOOST_TYPE_ERASURE_MEMBER((HasTest), Test, 1)
using Any = boost::type_erasure::any <
boost::mpl::vector <
HasTest<void(Type&)>,
boost::type_erasure::destructible<>,
boost::type_erasure::relaxed
>
>;
int main() {
Any obj;
}
Однако компилятор (например, clang) жалуется на неполный тип:
/usr/local/include/boost/type_traits/is_base_and_derived.hpp:228:42: error: incomplete type 'Type' used in type trait expression
BOOST_STATIC_CONSTANT(bool, value = (BOOST_IS_BASE_OF(B,D) && ! ::boost::is_same<ncvB,ncvD>::value));
Наконец, мне нужно обойти, изменив API со ссылки на указатель, то есть заменить тип& с типом *.
Проблема:
Можно ли заставить приведенный выше код работать?
В вашем коде есть несколько ошибок. Во-первых, макрос BOOST_TYPE_ERASURE_MEMBER
принимает аргумент для количества аргументов, которые принимает функция-член. Итак, вы хотите:
BOOST_TYPE_ERASURE_MEMBER((HasTest), Test, 1)
Следующий, any
на основе Concept
, который может быть списком понятий. Вы забыли часть списка, поэтому вам нужно:
using Any = any<boost::mpl::vector<
HasTest<void(Type&)>,
relaxed
>>;
Иначе, relaxed
не был включен в Concept
— который позволяет для строительства по умолчанию. Далее, вы не допустили разрушения в вашем any
, так что вы получаете ошибки компиляции на ~any()
, Вам необходимо дополнительно предоставить destructible<>
.
И, наконец, вы можете определить свой Any
с заранее объявленным типом. Это просто должно быть завершено типом, который вы используете. Следующие компиляции:
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/member.hpp>
namespace mpl = boost::mpl;
using namespace boost::type_erasure;
struct Type;
BOOST_TYPE_ERASURE_MEMBER((HasTest), Test, 1)
using Any = any<mpl::vector<
HasTest<void(Type&)>,
relaxed,
destructible<>
>>;
struct Type { };
int main() {
Any obj;
}