【问题标题】:What's the deal with BOOST_FUSION_ADAPT_STRUCT with more than 64 members?超过 64 个成员的 BOOST_FUSION_ADAPT_STRUCT 怎么办?
【发布时间】:2016-12-21 11:08:16
【问题描述】:

尝试为具有超过 64 个成员和 BOOST_FUSION_ADAPT_STRUCT 宏的大型结构创建样板代码,但它无法在 VS2015 Update 3 中编译。我尝试使用 BOOST_FUSION_HAS_VARIADIC_VECTORBOOST_PP_LIMIT_TUPLE 但没有运气,如果我将超过 64 个成员添加到 BOOST_FUSION_ADAPT_STRUCT,我会不断收到相同的错误。没有发现任何提及 BOOST_FUSION_ADAPT_STRUCT 的限制,除非它处于 C++03 模式。我错过了什么吗?

直播Coliru

代码:

#include <boost/fusion/adapted/struct/adapt_struct.hpp>

struct Data
{
    int a01 = 1;
    int a02 = 1;
    int a03 = 1;
    int a04 = 1;
    int a05 = 1;
    int a06 = 1;
    int a07 = 1;
    int a08 = 1;
    int a09 = 1;
    int a10 = 1;
    int a11 = 1;
    int a12 = 1;
    int a13 = 1;
    int a14 = 1;
    int a15 = 1;
    int a16 = 1;
    int a17 = 1;
    int a18 = 1;
    int a19 = 1;
    int a20 = 1;
    int a21 = 1;
    int a22 = 1;
    int a23 = 1;
    int a24 = 1;
    int a25 = 1;
    int a26 = 1;
    int a27 = 1;
    int a28 = 1;
    int a29 = 1;
    int a30 = 1;
    int a31 = 1;
    int a32 = 1;
    int a33 = 1;
    int a34 = 1;
    int a35 = 1;
    int a36 = 1;
    int a37 = 1;
    int a38 = 1;
    int a39 = 1;
    int a40 = 1;
    int a41 = 1;
    int a42 = 1;
    int a43 = 1;
    int a44 = 1;
    int a45 = 1;
    int a46 = 1;
    int a47 = 1;
    int a48 = 1;
    int a49 = 1;
    int a50 = 1;
    int a51 = 1;
    int a52 = 1;
    int a53 = 1;
    int a54 = 1;
    int a55 = 1;
    int a56 = 1;
    int a57 = 1;
    int a58 = 1;
    int a59 = 1;
    int a60 = 1;
    int a61 = 1;
    int a62 = 1;
    int a63 = 1;
    int a64 = 1;
    int a65 = 1;
    int a66 = 1;
    int a67 = 1;
    int a68 = 1;
    int a69 = 1;
    int a70 = 1;
};

BOOST_FUSION_ADAPT_STRUCT(Data, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, a11, a12, a13, a14, a15, a16, a17,
                          a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36,
                          a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, a55,
                          a56, a57, a58, a59, a60, a61, a62, a63/*, a64, a65, a66, a67, a68, a69, a70*/) // uncomment the a64 to get the error


int main()
{
    return 0;
}

MSVC 错误:

1>consoleapplication23.cpp(119):警告 C4003:实际不足 宏“BOOST_PP_SEQ_ELEM_III”的参数 1>consoleapplication23.cpp(119): 错误 C2065: 'BOOST_PP_SEQ_ELEM_0': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2146: 语法错误:标识符前缺少“>” 'BOOST_PP_TUPLE_TO_SEQ_a64' 1>consoleapplication23.cpp(119): 错误 C2065:'a01':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a02”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a03': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a04': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a05”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a06':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a07”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a08': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a09': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a10”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a11':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a12”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a13': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a14': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a15”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a16':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a17”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a18': 未声明 标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a19': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a20”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a21':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a22”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a23': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a24': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a25”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a26':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a27”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a28': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a29': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a30”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a31':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a32”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a33': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a34': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a35”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a36':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a37”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a38': 未声明 标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a39': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a40”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a41':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a42”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a43': 未声明 标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a44': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a45”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a46':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a47”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a48': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a49': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a50”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a51':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a52”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a53': 未声明 标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a54': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: 'a55': 未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:'a56':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a57”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a58': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a59': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a60”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a61':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a62”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a63': 未声明 标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a64': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a65”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a66':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a67”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a68': 未声明 标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a69': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a70”:未声明的标识符 1>consoleapplication23.cpp(116):错误 C2059:语法错误:')' 1>consoleapplication23.cpp(119):错误 C2977: 'boost::fusion::traits::tag_of':模板参数太多 1> 包\boost.1.61.0.0\lib\native\include\boost\fusion\support\tag_of.hpp(71): 注意:见'boost::fusion::traits::tag_of'的声明 1>consoleapplication23.cpp(119): 错误 C2913: 显式特化; 'boost::fusion::traits::tag_of' 不是一个类的特化 模板 1>consoleapplication23.cpp(119):错误 C2913:显式 专业化; 'boost::fusion::traits::tag_of' 不是 类模板的特化 1>consoleapplication23.cpp(119): 错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 没有 支持默认整数 1>consoleapplication23.cpp(119):错误 C2440: 'initializing': 无法从'initializer list' 转换为'int' 1> consoleapplication23.cpp(119):注意:初始化器包含太多 元素 1>consoleapplication23.cpp(116):错误 C2059:语法错误: '(' 1>consoleapplication23.cpp(119): 错误 C2065: 'BOOST_PP_SEQ_ELEM_0':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2146: 语法错误: 缺失 '>' 在标识符 'BOOST_PP_TUPLE_TO_SEQ_a64' 之前 1>consoleapplication23.cpp(119): 错误 C2065: 'a01': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a02': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a03”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a04':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a05”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a06': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a07': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a08”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a09':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a10”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a11': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a12': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: 'a13': 未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:'a14':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a15”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a16': 未声明 标识符 1>consoleapplication23.cpp(119):错误 C2065:'a17': 未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065: “a18”:未声明的标识符 1>consoleapplication23.cpp(119):错误 C2065:'a19':未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065:“a20”:未声明的标识符 1>consoleapplication23.cpp(119): 错误 C2065: 'a21': 未声明 标识符 1>consoleapplication23.cpp(119):致命错误 C1003:错误 计数超过 100;停止编译

GCC 错误:

main.cpp:80:1:错误:宏“BOOST_PP_SEQ_ELEM_III”需要 2 参数,但只给出了 1 个 a56, a57, a58, a59, a60, a61, a62, a63, a64, a65, a66, a67, a68, a69, a70) // 取消注释 a64 以获得 错误 ^ 在包含的文件中 /usr/local/include/boost/preprocessor/seq/seq.hpp:16:0, 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:20, 来自 main.cpp:1: main.cpp:77:1: 错误: 'BOOST_PP_SEQ_ELEM_III' 未在此范围内声明 BOOST_FUSION_ADAPT_STRUCT(数据,a01,a02,a03,a04,a05,a06,a07, a08、a09、a10、a11、a12、a13、a14、a15、a16、a17、^ 包含在文件中 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:28:0, 来自 main.cpp:1: main.cpp:77:1: 错误:模板参数 1 无效 BOOST_FUSION_ADAPT_STRUCT(Data, a01, a02, a03, a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15,a16,a17, ^ 在包含的文件中 /usr/local/include/boost/preprocessor/seq/seq.hpp:16:0, 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:20, 来自 main.cpp:1: main.cpp:77:1: 错误: 'BOOST_PP_SEQ_ELEM_III' 未在此范围内声明 BOOST_FUSION_ADAPT_STRUCT(数据,a01,a02,a03,a04,a05,a06,a07, a08、a09、a10、a11、a12、a13、a14、a15、a16、a17、^ 包含在文件中 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:28:0, 来自 main.cpp:1: main.cpp:77:1: 错误:模板参数 1 无效 BOOST_FUSION_ADAPT_STRUCT(Data, a01, a02, a03, a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15,a16,a17, ^ 在包含的文件中 /usr/local/include/boost/preprocessor/control/if.hpp:18:0, 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:17, 来自 main.cpp:1: main.cpp:77:1: 错误:'BOOST_PP_IIF_0' 没有命名类型 BOOST_FUSION_ADAPT_STRUCT(Data, a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14, a15, a16, a17, ^ 在包含的文件中 /usr/local/include/boost/preprocessor/seq/seq.hpp:16:0, 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:20, 来自 main.cpp:1: main.cpp:77:1: 错误: 'BOOST_PP_SEQ_ELEM_III' 未在此范围内声明 BOOST_FUSION_ADAPT_STRUCT(数据,a01,a02,a03,a04,a05,a06,a07, a08、a09、a10、a11、a12、a13、a14、a15、a16、a17、^ 包含在文件中 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:28:0, 来自 main.cpp:1: main.cpp:77:1: 错误:模板参数 1 无效 BOOST_FUSION_ADAPT_STRUCT(Data, a01, a02, a03, a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15,a16,a17, ^ 在包含的文件中 /usr/local/include/boost/preprocessor/seq/seq.hpp:16:0, 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:20, 来自 main.cpp:1: main.cpp:77:1: 错误: 'BOOST_PP_SEQ_ELEM_III' 未在此范围内声明 BOOST_FUSION_ADAPT_STRUCT(数据,a01,a02,a03,a04,a05,a06,a07, a08、a09、a10、a11、a12、a13、a14、a15、a16、a17、^ 包含在文件中 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:28:0, 来自 main.cpp:1: main.cpp:77:1: 错误:模板参数 1 无效 BOOST_FUSION_ADAPT_STRUCT(Data, a01, a02, a03, a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15,a16,a17, ^ 在包含的文件中 /usr/local/include/boost/preprocessor/seq/seq.hpp:16:0, 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:20, 来自 main.cpp:1: main.cpp:77:1: 错误: 'BOOST_PP_SEQ_ELEM_III' 未在此范围内声明 BOOST_FUSION_ADAPT_STRUCT(数据,a01,a02,a03,a04,a05,a06,a07, a08、a09、a10、a11、a12、a13、a14、a15、a16、a17、^ 包含在文件中 从 /usr/local/include/boost/fusion/adapted/struct/adapt_struct.hpp:28:0, 来自 main.cpp:1: main.cpp:77:1: 错误:模板参数 1 无效 BOOST_FUSION_ADAPT_STRUCT(Data, a01, a02, a03, a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15,a16,a17, ^

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

【问题讨论】:

标签: c++ visual-c++ visual-studio-2015 boost-fusion


【解决方案1】:

看起来BOOST_FUSION_ADAPT_STRUCT 每个类元素有两个参数,类型和名称。 MSVC 仅支持127 macro parameters,而标准建议使用 255。这就解释了为什么需要 128 个宏参数的第 64 个元素在 MSVC++ 上编译失败。

【讨论】:

  • BOOST_FUSION_ADAPT_STRUCT 每个类元素只需要 1 个参数,即其名称。见boost.org/doc/libs/1_61_0/libs/fusion/doc/html/fusion/adapted/…
  • 由于 Coliru 在同一个第 64 个元素上失败了,我猜 CGG 也有同样的限制,或者更有可能是 Boost Fusion 中的某些东西限制了它
  • @m.s.:在这种情况下,它使用Boost.TypeOf 来确定类型。我敢打赌,在宏扩展期间会为您提供宏参数 64-128。
  • 限制似乎在 Boost.Preprocessor 中,特别是在 BOOST_PP_VARIADIC_TO_SEQ 宏中。 Simple test.
  • 更改 BOOST_PP_TUPLE_TO_SEQ 和 BOOST_PP_VARIADIC_SIZE 似乎是make it work for 64 elements
【解决方案2】:

发生这种情况是因为 BOOST_PP_TUPLE_TO_SEQ() 仅针对 0 到 64 个参数实现(其中一个由 BOOST_FUSION_ADAPT_STRUCT() 中的类型采用)。

参考:https://www.boost.org/doc/libs/1_67_0/boost/preprocessor/tuple/to_seq.hpp

作为一种解决方法,您可以将一些结构成员放入它们自己的结构中,并将该结构类型用作外部结构中的成员。这让您可以调用BOOST_FUSION_ADAPT_STRUCT() 两次:每个内部结构类型调用一次,外部结构类型调用一次。这很容易为您提供 63*63 = 3969 个最大字段。

【讨论】:

    【解决方案3】:

    如果你调用没有BOOST_PP_VARIADICS支持的版本,你可以避免BOOST_PP_TUPLE_TO_SEQ()的这个限制

    BOOST_FUSION_ADAPT_STRUCT(Data,
    (auto,a01)(auto,a02)(auto,a03)(auto,a04)(auto,a05)(auto,a06)(auto,a07)(auto,a08)(auto,a09)(auto,a10)
    (auto,a11)(auto,a12)(auto,a13)(auto,a14)(auto,a15)(auto,a16)(auto,a17)(auto,a18)(auto,a19)(auto,a20)
    (auto,a21)(auto,a22)(auto,a23)(auto,a24)(auto,a25)(auto,a26)(auto,a27)(auto,a28)(auto,a29)(auto,a30)
    (auto,a31)(auto,a32)(auto,a33)(auto,a34)(auto,a35)(auto,a36)(auto,a37)(auto,a38)(auto,a39)(auto,a40)
    (auto,a41)(auto,a42)(auto,a43)(auto,a44)(auto,a45)(auto,a46)(auto,a47)(auto,a48)(auto,a49)(auto,a50)
    (auto,a51)(auto,a52)(auto,a53)(auto,a54)(auto,a55)(auto,a56)(auto,a57)(auto,a58)(auto,a59)(auto,a60)
    (auto,a61)(auto,a62)(auto,a63)(auto,a64)(auto,a65)(auto,a66)(auto,a67)(auto,a68)(auto,a69)(auto,a70))
    

    我无法使用 MSVC 对其进行测试,但它适用于 gcc。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多