c++使用 boost-mpl 进行编译时字符串连接

发布于 2024-11-08 12:26:25 字数 3658 浏览 5 评论 0原文

我尝试使用 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: 在 Lambdaageek、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’

I'm trying to concatenate strings at compile-time using boost-mpl but am getting errors from gcc. Here's the sample -

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;
};

So, what i'm trying to achieve is :

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

Problem is that the above code in gcc throws the following errors:

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’

Could anyone point out the problem with the above code and explain the right way to do it ? Thanks

EDIT 1: corrected formatting and few typos

EDIT 2:
After Lambdageek, Andy's suggestion the code does compile but when i try to print the result

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

, compiler complains -

/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

I admit that i'm very new to template programming, so am sure the problem must be something elementary. Thanks for all the help

EDIT 3: Changed the push_back line in converter struct.

Errors:

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’

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒几许 2024-11-15 12:26:25

好的,根据您的最终编辑,我在这里看到了几个问题。

首先,您可以使用 mpl::push_back 向序列添加元素。现在您正在连接两个序列。我将 type<>::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)。

OK, as per your final edits, I see several problems here.

First, you can use mpl::push_back to add an element to a sequence. Now you're concatenating two sequences. I changed the type of type<>::value to mpl::char_, then changed the order of the mpl::push_back arguments (first the sequence, then the element). Also, you have to use push_front, not push_back in this code. Finally, I added a ::type after the push_front, because you have to extract the actual type here. Here is the code for reference:

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;
};

Now this code works as expected:

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

(prints ic).

全部不再 2024-11-15 12:26:25

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

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

Does it help to add the typename keyword, to tell the compiler that ::value is a type?

struct converter {
    typedef mpl::push_back< typename type<A>::value, typename converter<B,C,D>::value > value ;
};
诠释孤独 2024-11-15 12:26:25

您需要使用 typename 关键字:

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

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

You need to use the typename keyword:

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

When accessing a nested typedef of a template that is instantiated with your template arguments, you
need to help C++ decide whether the nested name refers to a method/field or to a nested type definition.
If you don't say anything, C++ will assume it's a field name. If you say typename it will assume the
nested thing is a type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文