【问题标题】:c++ compile-time string concatenation using boost-mpl使用 boost-mpl 的 c++ 编译时字符串连接
【发布时间】:2011-05-17 20:59:01
【问题描述】:

我试图在编译时使用 boost-mpl 连接字符串,但我从 gcc 收到错误。这是示例 -

using namespace boost;
using namespace std;

template<class A>
struct type {};

template<>
struct type<int> {
    typedef mpl::string < 'i' > value;
};

template<>
struct type<char> {
    typedef mpl::string < 'c' > value;
};

struct empty {
};

template<class A, class B, class C, class D>
struct converter;

template<class A, class B = empty, class C = empty, class D = empty>

struct converter {
    typedef mpl::push_back< type<A>::value, converter<B,C,D>::value >::type value ;
};

template<>
struct converter<empty, empty, empty, empty> {
    typedef mpl::string < '\0' > value;
};

所以,我想要实现的是:

converter<int,char,int> == "ici\0" // true. 

问题是上面gcc中的代码抛出如下错误:

main.cpp:37: error: type/value mismatch at argument 1 in template parameter list for ‘template<class Sequence, class T> struct boost::mpl::push_back’
main.cpp:37: error:   expected a type, got ‘type::value’
main.cpp:37: error: type/value mismatch at argument 2 in template parameter list for ‘template<class Sequence, class T> struct boost::mpl::push_back’
main.cpp:37: error:   expected a type, got ‘converter::value’

谁能指出上述代码的问题并解释正确的方法?谢谢

编辑 1:更正格式和少量拼写错误

编辑 2: 在 Lambdageek 之后,Andy 的建议代码确实可以编译,但是当我尝试打印结果时

int main(int argc, char** argv) {
    cout << mpl::c_str< converter<int,char>::value >::value << endl;
    return 0;
}

,编译器报错 -

/usr/local/include/boost/mpl/string.hpp:534:   instantiated from ‘boost::mpl::c_str<boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::string<0, 0, 0, 0, 0, 0, 0, 0> > > >’
main.cpp:49:   instantiated from here

/usr/local/include/boost/mpl/string.hpp:228: error: ‘value’ is not a member of ‘boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::string<0, 0, 0, 0, 0, 0, 0, 0> >’

/usr/local/include/boost/mpl/string.hpp: In instantiation of ‘boost::mpl::c_str<boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::string<0, 0, 0, 0, 0, 0, 0, 0> > > >’:
main.cpp:49:   instantiated from here
/usr/local/include/boost/mpl/string.hpp:548: error: no type named ‘value_type’ in struct boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::string<0, 0, 0, 0, 0, 0, 0, 0> > >’
main.cpp: In function ‘int main(int, char**)’:
main.cpp:49: error: ‘value’ is not a member of ‘boost::mpl::c_str<boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::push_back<boost::mpl::string<105, 0, 0, 0, 0, 0, 0, 0>, boost::mpl::string<0, 0, 0, 0, 0, 0, 0, 0> > > >’
make[2]: *** [build/Debug/GNU-Linux-x86/main.o] Error 1
make[1]: *** [.build-conf] Error 2

我承认我对模板编程很陌生,所以我确信问题一定是基本的。感谢大家的帮助

编辑 3:更改了转换器结构中的 push_back 行。

错误:

main.cpp:41: error: type ‘boost::mpl::push_back<typename type<A>::value, typename converter<B, C, D, empty>::value>’ is not derived from type ‘converter<A, B, C, D>’
main.cpp:41: error: expected ‘;’ before ‘value’

【问题讨论】:

    标签: c++ string templates string-concatenation boost-mpl


    【解决方案1】:

    好的,根据您的最终编辑,我发现这里有几个问题。

    首先,您可以使用mpl::push_back 将元素添加到序列中。现在您正在连接两个序列。我将type&lt;&gt;::value 的类型更改为mpl::char_,然后更改了mpl::push_back 参数的顺序(首先是序列,然后是元素)。此外,您必须在此代码中使用push_front,而不是push_back。最后我在push_front后面加了::type,因为这里要提取实际类型。以下是参考代码:

    using namespace boost;
    using namespace std;
    
    template<class A>
    struct type {};
    
    template<>
    struct type<int> {
        typedef mpl::char_ < 'i' > value;
    };
    
    template<>
    struct type<char> {
        typedef mpl::char_ < 'c' > value;
    };
    
    struct empty {
    };
    
    template<class A, class B, class C, class D>
    struct converter;
    
    
    template<class A, class B = empty, class C = empty, class D = empty>
    struct converter {
            typedef typename mpl::push_front< typename converter<B,C,D>::value, typename type<A>::value >::type value ;
    };
    
    
    template<>
    struct converter<empty, empty, empty, empty> {
        typedef mpl::string < '\0' > value;
    };
    

    现在这段代码可以正常工作了:

    int
    main (void)
    {
            cout << mpl::c_str< converter<int,char>::value >::value << endl;
            return 0;
    }
    

    (打印ic)。

    【讨论】:

    • 那行得通。万分感谢。但只是好奇,有没有办法使用 mpl::string 而不是 char_ 来做同样的事情?另外,我赞成但不能将其标记为答案,因为 lambdageek 已经回答了原始问题 - 抱歉
    • @Code,你的问题的答案不会生成有效的代码:) 无论如何,我会研究如何在所有地方使用 mpl::string 来做到这一点,也许使用@987654332 @.
    • @Code:好的,可以了。类型必须是:typedef typename mpl::copy&lt; typename converter&lt;B,C,D&gt;::value, mpl::back_inserter&lt; typename type&lt;A&gt;::value &gt; &gt;::type value;。这会将 type::value 中的所有字符添加到转换器字符串的后面。
    • 谢谢。看起来很复杂,但应该试一试:)
    【解决方案2】:

    添加typename 关键字是否有助于告诉编译器::value 是一种类型?

    struct converter {
        typedef mpl::push_back< typename type<A>::value, typename converter<B,C,D>::value > value ;
    };
    

    【讨论】:

    • 谢谢。请检查更新的问题。代码现在可以编译,但是当我添加代码以打印结果时我再次出错。
    【解决方案3】:

    你需要使用typename关键字:

    typedef mpl::push_back< typename type<A>::value, typename converter<B,C,D>>:value >::type value;
    

    当访问使用模板参数实例化的模板的嵌套 typedef 时,您 需要帮助 C++ 决定嵌套名称是指方法/字段还是嵌套类型定义。 如果你什么都不说,C++ 将假定它是一个字段名。如果您说typename,它将假定 嵌套的东西是一种类型。

    【讨论】:

    • 谢谢。您的建议有效,但是当我尝试打印值时出现新错误,请检查对问题的编辑。
    • 尝试将::type 添加到push_back 行。请参阅the Boost documentation 中的示例
    • 将该行更改为 typedef mpl::push_back::value, typename converter::value >::type value ;但现在我得到 main.cpp:41: error: type 'boost::mpl::push_back::value, typename converter::value>' 是不是从类型 'converter' 派生的
    • @Code:你的键盘有问题。 “你”总是通过“你”来的。此外,大写的“我”似乎被打破了。您可能想要一个新键盘。
    猜你喜欢
    • 2013-06-25
    • 2010-12-18
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    相关资源
    最近更新 更多