尝试在旧代码中用新的 boost 替换旧的 boost 并得到错误,“type”:不是 boost::mpl::eval_if 的成员

问题描述 投票:0回答:1

我尝试用新版本的 boost 1.86 来编译使用非常旧的 boost 版本(例如 1.30 之类)的旧代码(~15 年前 - luabind)。

我用

apply_if
替换了一些
eval_if
用法,就像 boost 1.32 发行说明中建议的那样。但是我遇到了一些编译错误。我尝试在下面准备一些有问题的代码的最小示例。

#include <boost/mpl/end.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/move/detail/meta_utils.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/list/list10.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/preprocessor/enum_params_with_a_default.hpp>

#include <iostream>

struct unspecified {
    typedef unspecified type;
};

template<class T, class X1 = unspecified, class X2 = unspecified, class X3 = unspecified>
struct class_;

double is_not_unspecified_helper(const unspecified*);
char is_not_unspecified_helper(...);

template<class T>
struct is_not_unspecified
{
    BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
    typedef boost::mpl::bool_<value> type;
    BOOST_MPL_AUX_LAMBDA_SUPPORT(1, is_not_unspecified, (T))
};

template<class Predicate>
struct get_predicate
{
    typedef typename boost::mpl::and_<
        Predicate
        , is_not_unspecified<boost::mpl::_1>
    > type;
};

template<class Parameters, class Predicate, class DefaultValue>
struct extract_parameter
{
    typedef typename get_predicate<Predicate>::type pred;
    typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
    typedef typename boost::mpl::eval_if<boost::is_same<iterator, typename boost::mpl::end<Parameters>::type>
        , boost::mpl::identity<DefaultValue>
        , iterator
    >::type type;
};


template<class T, class X1, class X2, class X3>
struct class_ {

    class_(const char* name)
    {
        std::printf("class_(%s)\n", name);
    }

    typedef typename extract_parameter<
        boost::mpl::list3<X1, X2, X3>
        , boost::mpl::or_<
            boost::is_base_and_derived<boost::mpl::_, T>
        ,   boost::is_base_and_derived<boost::mpl::_, T>
        >
        , unspecified
    >::type bases_t;
};

class A {
public:
    typedef A type;
};

class B :
    public A
{

public:
    typedef B type;

    void foo()
    {
        class_<B, A>("B");
    }
};

int main()
{
}

编译错误:

1>main.cpp(50,5): error C2039: 'type': is not a member of 'boost::mpl::eval_if<boost::is_same<Iterator,LastIterator>,boost::mpl::identity<DefaultValue>,boost::mpl::l_iter<boost::mpl::list3<X1,X2,X3>>>'
1>main.cpp(50,5): error C2039:         with
1>main.cpp(50,5): error C2039:         [
1>main.cpp(50,5): error C2039:             Iterator=boost::mpl::l_iter<boost::mpl::list3<A,unspecified,unspecified>>,
1>main.cpp(50,5): error C2039:             LastIterator=boost::mpl::l_iter<boost::mpl::l_end>,
1>main.cpp(50,5): error C2039:             DefaultValue=unspecified,
1>main.cpp(50,5): error C2039:             X1=A,
1>main.cpp(50,5): error C2039:             X2=unspecified,
1>main.cpp(50,5): error C2039:             X3=unspecified
1>main.cpp(50,5): error C2039:         ]
1>main.cpp(50,10): error C3646: 'type': unknown override specifier
1>main.cpp(50,5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>Done building project "eval_if_compilation.vcxproj" -- FAILED.

我很确定原因与

extract_parameter::iterator
类型定义有关。当我用简单的
unspecified
结构替换它时,它编译得很好。我相信原因是它找不到
iterator::type
类型。然而它定义良好,我不明白为什么它会导致错误。

c++ boost metaprogramming template-meta-programming luabind
1个回答
0
投票

看起来

identity<>
周围的包裹
iterator
不见了。

using type        = boost::mpl::eval_if<                                   //
    boost::is_same<iterator, typename boost::mpl::end<Parameters>>, //
    boost::mpl::identity<DefaultValue>,                             //
    boost::mpl::identity<iterator>                                  //
    >::type;

让它为我编译(修复包含)。

住在Coliru

#include <boost/move/detail/meta_utils.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/list/list10.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/preprocessor/enum_params_with_a_default.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <cstdio>

struct unspecified {
    typedef unspecified type;
};

template<class T, class X1 = unspecified, class X2 = unspecified, class X3 = unspecified>
struct class_;

double is_not_unspecified_helper(const unspecified*);
char is_not_unspecified_helper(...);

template<class T>
struct is_not_unspecified
{
    BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
    typedef boost::mpl::bool_<value> type;
    BOOST_MPL_AUX_LAMBDA_SUPPORT(1, is_not_unspecified, (T))
};

template<class Predicate>
struct get_predicate
{
    typedef typename boost::mpl::and_<
        Predicate
        , is_not_unspecified<boost::mpl::_1>
    > type;
};

template<class Parameters, class Predicate, class DefaultValue>
struct extract_parameter
{
    using pred        = typename get_predicate<Predicate>::type;
    using iterator    = typename boost::mpl::find_if<Parameters, pred>::type;
    using type        = boost::mpl::eval_if<                                   //
        boost::is_same<iterator, typename boost::mpl::end<Parameters>>, //
        boost::mpl::identity<DefaultValue>,                             //
        boost::mpl::identity<iterator>                                  //
        >::type;
};

template<class T, class X1, class X2, class X3>
struct class_ {

    class_(char const* name) { std::printf("class_(%s)\n", name); }

    typedef typename extract_parameter<
        boost::mpl::list3<X1, X2, X3>
        , boost::mpl::or_<
            boost::is_base_and_derived<boost::mpl::_, T>
        ,   boost::is_base_and_derived<boost::mpl::_, T>
        >
        , unspecified
    >::type bases_t;
};

class A {
public:
    typedef A type;
};

class B :
    public A
{

public:
    typedef B type;

    void foo()
    {
        class_<B, A>("B");
    }
};

int main()
{
}
© www.soinside.com 2019 - 2024. All rights reserved.