gpt4 book ai didi

c++ - 使用 Boost.Preprocessor 生成一组带标签和索引的类模板特化

转载 作者:太空狗 更新时间:2023-10-29 21:35:45 27 4
gpt4 key购买 nike

需要创建一个宏来生成一组由标签和索引专门化的结构重载。我尝试了以下方法:

#include <boost/preprocessor/seq/for_each_i.hpp>

template< typename /*tag*/, int /*index*/ >
struct S;

#define GEN(ignored, tilda, index, type_name) \
template<> struct S< struct BOOST_PP_SEQ_TAIL(type_name), index > \
{ BOOST_PP_SEQ_HEAD(type_name) BOOST_PP_SEQ_TAIL(type_name); };

#if 1
BOOST_PP_SEQ_FOR_EACH_I(GEN, ~, ((int)(i)))
#else
// above should be equiv to:
template<> struct S< struct i, 0 > { int i; };
#endif

int main()
{
S< i, 0 >{}.i; // check if accessible
}

但是报错:

prog.cc:8:111: error: wrong number of template arguments (1, should be 2)
#define GEN(ignored, tilda, index, type_name) template<> struct S< struct BOOST_PP_SEQ_TAIL(type_name), index > { BOOST_PP_SEQ_HEAD(type_name) BOOST_PP_SEQ_TAIL(type_name); };
^
/usr/local/boost-1.62.0/include/boost/preprocessor/seq/for_each_i.hpp:85:66: note: in expansion of macro 'GEN'
# define BOOST_PP_SEQ_FOR_EACH_I_M_I(r, macro, data, seq, i, sz) macro(r, data, i, BOOST_PP_SEQ_HEAD(seq))
^~~~~
/usr/local/boost-1.62.0/include/boost/preprocessor/seq/for_each_i.hpp:80:49: note: in expansion of macro 'BOOST_PP_SEQ_FOR_EACH_I_M_I'
# define BOOST_PP_SEQ_FOR_EACH_I_M_IM(r, im) BOOST_PP_SEQ_FOR_EACH_I_M_I(r, im)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/boost-1.62.0/include/boost/preprocessor/seq/for_each_i.hpp:79:45: note: in expansion of macro 'BOOST_PP_SEQ_FOR_EACH_I_M_IM'
# define BOOST_PP_SEQ_FOR_EACH_I_M(r, x) BOOST_PP_SEQ_FOR_EACH_I_M_IM(r, BOOST_PP_TUPLE_REM_5 x)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/boost-1.62.0/include/boost/preprocessor/seq/for_each_i.hpp:79:77: note: in expansion of macro 'BOOST_PP_TUPLE_REM_5'
# define BOOST_PP_SEQ_FOR_EACH_I_M(r, x) BOOST_PP_SEQ_FOR_EACH_I_M_IM(r, BOOST_PP_TUPLE_REM_5 x)
^~~~~~~~~~~~~~~~~~~~
/usr/local/boost-1.62.0/include/boost/preprocessor/control/iif.hpp:32:31: note: in expansion of macro 'BOOST_PP_SEQ_FOR_EACH_I_M'
# define BOOST_PP_IIF_1(t, f) t
^
/usr/local/boost-1.62.0/include/boost/preprocessor/repetition/detail/for.hpp:22:37: note: in expansion of macro 'BOOST_PP_FOR_1_C'
# define BOOST_PP_FOR_1(s, p, o, m) BOOST_PP_FOR_1_C(BOOST_PP_BOOL(p(2, s)), s, p, o, m)
^~~~~~~~~~~~~~~~
/usr/local/boost-1.62.0/include/boost/preprocessor/cat.hpp:29:34: note: in expansion of macro 'BOOST_PP_FOR_1'
# define BOOST_PP_CAT_I(a, b) a ## b
^
/usr/local/boost-1.62.0/include/boost/preprocessor/control/iif.hpp:32:31: note: in expansion of macro 'BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK_EXEC'
# define BOOST_PP_IIF_1(t, f) t
^
/usr/local/boost-1.62.0/include/boost/preprocessor/seq/for_each_i.hpp:30:55: note: in expansion of macro 'BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK'
# define BOOST_PP_SEQ_FOR_EACH_I(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_I_DETAIL_CHECK(macro, data, seq)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:10:1: note: in expansion of macro 'BOOST_PP_SEQ_FOR_EACH_I'
BOOST_PP_SEQ_FOR_EACH_I(GEN, ~, ((int)(i)))
^~~~~~~~~~~~~~~~~~~~~~~
prog.cc:6:8: note: provided for 'template<class, long unsigned int <anonymous> > struct S'
struct S;
^
prog.cc: In function 'int main()':
prog.cc:16:8: error: 'i' was not declared in this scope
S< i, 0 >{}.i; // check if accessible
^
prog.cc:16:13: error: template argument 1 is invalid
S< i, 0 >{}.i; // check if accessible
^

宏的 struct BOOST_PP_SEQ_TAIL(type_name) 部分似乎无法正确处理,但为什么呢?如果我将第一次出现的 BOOST_PP_SEQ_TAIL(type_name) 替换为 i,则代码可以正常编译。

错误的来源是什么?

最佳答案

我删除了 #include <cstdint>为简洁起见,但尝试使用 -P -E 进行编译,这将只输出预处理器运行的结果,这在调试 Boost.PP 程序时非常有值(value)。

它的输出是:

template< typename , int >
struct S;
template<> struct S< struct (i), 0 > { int (i); };
int main()
{
S< i, 0 >{}.i;
}

错误很明显:struct (i)int (i)是无效语法。

This answer可能会帮助您解决这个问题。

这是我的解决方案,即创建我自己的小元组访问宏:

#include <boost/preprocessor/seq/for_each_i.hpp>

template< typename /*tag*/, int /*index*/ >
struct S;

#define FIRST(a, b) a
#define SECOND(a, b) b

#define GEN(ignored, tilda, index, type_name) \
template<> struct S< struct SECOND type_name, index > \
{ FIRST type_name SECOND type_name; };

#if 1
BOOST_PP_SEQ_FOR_EACH_I(GEN, ~, ((int, i)))
#else
// above should be equiv to:
template<> struct S< struct i, 0 > { int i; };
#endif

int main()
{
S< i, 0 >{}.i; // check if accessible
}

关于c++ - 使用 Boost.Preprocessor 生成一组带标签和索引的类模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41614314/

27 4 0