Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 提取uu VA_参数的第一个参数___C++_C++17 - Fatal编程技术网

C++ 提取uu VA_参数的第一个参数__

C++ 提取uu VA_参数的第一个参数__,c++,c++17,C++,C++17,假设我有一个宏: #define FOO(a, ...) if (a) foo(a, ## __VA_ARGS__) 这很有效: FOO(a)将转换为if(a)FOO(a) FOO(a,)将转换为if(a)FOO(a,) 是否可以修改此宏,以便只将\uu VA\u ARGS\uu的第一个参数(如果存在)传递给foo?因此,我需要: FOO(a)如果(a)FOO(a) FOO(a,b,)要转换为if(a)FOO(a,b) 我试图用与BOOST\u PP\u VARIADIC\u SIZE

假设我有一个宏:

#define FOO(a, ...) if (a) foo(a, ## __VA_ARGS__)
这很有效:

  • FOO(a)
    将转换为
    if(a)FOO(a)
  • FOO(a,)
    将转换为
    if(a)FOO(a,)
是否可以修改此宏,以便只将
\uu VA\u ARGS\uu
的第一个参数(如果存在)传递给
foo
?因此,我需要:

  • FOO(a)
    如果(a)FOO(a)
  • FOO(a,b,)
    要转换为
    if(a)FOO(a,b)
我试图用与
BOOST\u PP\u VARIADIC\u SIZE
相同的想法来解决这个问题,但结果是,对于
BOOST\u PP\u VARIADIC\u SIZE()
(空参数),这个宏返回
1
,这是不期望的(我期望
0

请注意,我需要一个解决方案,其中只有当
bool(a)
true

时才对
b
进行评估。基于此,我可以解决问题:

#define PRIVATE_CONCAT(a, b) a ## b

#define CONCAT(a, b) PRIVATE_CONCAT(a, b)

#define GET_100TH( \
    _01, _02, _03, _04, _05, _06, _07, _08, _09, _10,  \
    _11, _12, _13, _14, _15, _16, _17, _18, _19, _20,  \
    _21, _22, _23, _24, _25, _26, _27, _28, _29, _30,  \
    _31, _32, _33, _34, _35, _36, _37, _38, _39, _40,  \
    _41, _42, _43, _44, _45, _46, _47, _48, _49, _50,  \
    _51, _52, _53, _54, _55, _56, _57, _58, _59, _60,  \
    _61, _62, _63, _64, _65, _66, _67, _68, _69, _70,  \
    _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,  \
    _81, _82, _83, _84, _85, _86, _87, _88, _89, _90,  \
    _91, _92, _93, _94, _95, _96, _97, _98, _99, PAR,  \
    ...) PAR

#define HAS_PARAMETER(...) GET_100TH(placeholder, ##__VA_ARGS__, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 0)

#define FIRST_PARAMETER_WITH_PREPENDED_COMMA0(...)
#define FIRST_PARAMETER_WITH_PREPENDED_COMMA1(a, ...) , a

#define FIRST_PARAMETER_WITH_PREPENDED_COMMA(...) CONCAT(FIRST_PARAMETER_WITH_PREPENDED_COMMA, HAS_PARAMETER(__VA_ARGS__))(__VA_ARGS__)

#define FOO(a, ...) if (a) foo(a FIRST_PARAMETER_WITH_PREPENDED_COMMA(__VA_ARGS__))
基于此,我可以解决这个问题:

#define PRIVATE_CONCAT(a, b) a ## b

#define CONCAT(a, b) PRIVATE_CONCAT(a, b)

#define GET_100TH( \
    _01, _02, _03, _04, _05, _06, _07, _08, _09, _10,  \
    _11, _12, _13, _14, _15, _16, _17, _18, _19, _20,  \
    _21, _22, _23, _24, _25, _26, _27, _28, _29, _30,  \
    _31, _32, _33, _34, _35, _36, _37, _38, _39, _40,  \
    _41, _42, _43, _44, _45, _46, _47, _48, _49, _50,  \
    _51, _52, _53, _54, _55, _56, _57, _58, _59, _60,  \
    _61, _62, _63, _64, _65, _66, _67, _68, _69, _70,  \
    _71, _72, _73, _74, _75, _76, _77, _78, _79, _80,  \
    _81, _82, _83, _84, _85, _86, _87, _88, _89, _90,  \
    _91, _92, _93, _94, _95, _96, _97, _98, _99, PAR,  \
    ...) PAR

#define HAS_PARAMETER(...) GET_100TH(placeholder, ##__VA_ARGS__, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
        1, 1, 1, 1, 1, 1, 1, 1, 0)

#define FIRST_PARAMETER_WITH_PREPENDED_COMMA0(...)
#define FIRST_PARAMETER_WITH_PREPENDED_COMMA1(a, ...) , a

#define FIRST_PARAMETER_WITH_PREPENDED_COMMA(...) CONCAT(FIRST_PARAMETER_WITH_PREPENDED_COMMA, HAS_PARAMETER(__VA_ARGS__))(__VA_ARGS__)

#define FOO(a, ...) if (a) foo(a FIRST_PARAMETER_WITH_PREPENDED_COMMA(__VA_ARGS__))

我提出了一个带有通用lambda的可变宏作为解决方案。 要点如下:

  • 很难将
    a
    \uuuuu-VA\u-ARGS\uuuu
    作为宏中的传递参数传递给lambda,因为当
    \uu-VA\u-ARGS\uu
    为空时

    [](){...}(a, __VA_ARGS__)
    
    变成

    [](){...}(a,)
    
    而这
    导致编译错误。 因此,我们将
    FOO
    的第一个和第二个参数分别拆分为捕获的参数和传递的参数,如下所示。
    然后,我们可以在宏中使用通用lambda,即使
    \uu VA\u ARGS\uu
    为空

    [a](){...}(__VA_ARGS__)
    
  • 的大小可以在编译时作为
    constexpr auto N
    进行计算。然后我们可以使用
    if constexpr
    来分隔函数调用

  • 我们还可以应用带有初始值设定项的if语句,该初始值设定项是从C++17引入的,用于
    if(a)

然后,建议的宏如下所示。 这也适用于你

#包括
#定义FOO(a,…)\
如果(常数布尔a=(a);a)\
[a](自动&&…参数)\
{                                                                             \
const auto t=std::make_tuple(std::forward(args)…)\
constexpr auto N=std::tuple\u size::value\
\
如果constexpr(N==0){\
返回foo(a_)\
}                                                                          \
否则{\
返回foo(a_,std::get(t))\
}                                                                          \
}(uu VA_uargs_uu)

我建议使用一个带有通用lambda的可变宏作为解决方案。 要点如下:

  • 很难将
    a
    \uuuuu-VA\u-ARGS\uuuu
    作为宏中的传递参数传递给lambda,因为当
    \uu-VA\u-ARGS\uu
    为空时

    [](){...}(a, __VA_ARGS__)
    
    变成

    [](){...}(a,)
    
    而这
    导致编译错误。 因此,我们将
    FOO
    的第一个和第二个参数分别拆分为捕获的参数和传递的参数,如下所示。
    然后,我们可以在宏中使用通用lambda,即使
    \uu VA\u ARGS\uu
    为空

    [a](){...}(__VA_ARGS__)
    
  • 的大小可以在编译时作为
    constexpr auto N
    进行计算。然后我们可以使用
    if constexpr
    来分隔函数调用

  • 我们还可以应用带有初始值设定项的if语句,该初始值设定项是从C++17引入的,用于
    if(a)

然后,建议的宏如下所示。 这也适用于你

#包括
#定义FOO(a,…)\
如果(常数布尔a=(a);a)\
[a](自动&&…参数)\
{                                                                             \
const auto t=std::make_tuple(std::forward(args)…)\
constexpr auto N=std::tuple\u size::value\
\
如果constexpr(N==0){\
返回foo(a_)\
}                                                                          \
否则{\
返回foo(a_,std::get(t))\
}                                                                          \
}(uu VA_uargs_uu)

可能重复@Frank:谢谢你发现这个问题,基于此,我可以解决这个问题。你真的需要宏吗?简单重载似乎可以完成这项工作。@Jarod42:是的,需要宏,因为我需要懒洋洋地计算FOO的参数(我的意思是,在实际代码中,当某些条件为true时,我只调用
FOO
。如果该条件为false,则不调用
FOO
,也不计算其参数)。@geza是
a
的类型,
b
都一样吗?可能重复@Frank:谢谢你发现这个问题,基于此我可以解决这个问题。你真的需要宏吗?简单重载似乎可以完成这项工作。@Jarod42:是的,需要宏,因为我需要惰性地计算FOO的参数(我的意思是,在实际代码中,我只调用
FOO
,w