gpt4 book ai didi

c++ - C可变参数宏调用另一个可变参数宏

转载 作者:太空宇宙 更新时间:2023-11-04 02:02:59 25 4
gpt4 key购买 nike

我有以下代码(原样):

template<class T, class FieldT>
using addRefU = typename std::conditional<
std::is_rvalue_reference<T>::value,
typename std::add_rvalue_reference< FieldT >::type,
typename std::conditional<
std::is_rvalue_reference<FieldT>::value,
typename std::add_rvalue_reference< FieldT >::type,
typename std::add_lvalue_reference< FieldT >::type
>::type
>::type;

#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(X,##__VA_ARGS__, 4, 3, 2, 1, 0)
#define VARARG_IMPL2(base, count, ...) base##count(__VA_ARGS__)
#define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__)
#define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__)


#define REF2(val, p1) addRefU<decltype(val), decltype(val.p1)>
#define REF3(val, p1, p2) addRefU<decltype(val), decltype(val.p1.p2)>
#define REF4(val, p1, p2, p3) addRefU<decltype(val), decltype(val.p1.p2.p3)>
#define REF5(val, p1, p2, p3, p4) addRefU<decltype(val), decltype(val.p1.p2.p3.p4)>
#define REF(...) VARARG(REF, __VA_ARGS__) // It says REF is not defined here



#define CAST_REF2(val, p1) static_cast<REF(val, p1)>(val.p1)
#define CAST_REF3(val, p1, p2) static_cast<REF(val, p1, p2)>(val.p1.p2)
#define CAST_REF4(val, p1, p2, p3) static_cast<REF(val, p1, p2, p3)>(val.p1.p2.p3)
#define CAST_REF5(val, p1, p2, p3, p4) static_cast<REF(val, p1, p2, p3, p4)>(val.p1.p2.p3.p4)
#define CAST_REF(...) VARARG(CAST_REF, __VA_ARGS__)


struct A{};
struct B{A a;};

int main()
{
B b;

using t = REF(b, a); // Ok

auto &&k = CAST_REF2(b, a); // work
auto &&k1 = CAST_REF(b, a); // NOT work

return 0;
}

http://coliru.stacked-crooked.com/a/8dff49f68b7e15e1

如果我改变

#define CAST_REF2(val, p1) static_cast<REF(val, p1)>(val.p1)

#define CAST_REF2(val, p1) static_cast<REF2(val, p1)>(val.p1) (将 REF 更改为 REF2 )

它有效。我不明白为什么我可以打电话REF直接,不能从宏中执行此操作。

最佳答案

您的代码(不包含)preprocesses to the following :

struct A{};
struct B{A a;};

int main()
{
B b;

using t = addRefU<decltype(b), decltype(b.a)>

auto &&k = static_cast<VARARG(REF, b, a)>(b.a);
auto &&k1 = static_cast<addRefU<decltype(b), decltype(b.a)> >(b.a);

return 0;
}

很明显,VARARG没有展开,这是因为之前在CAST_REF的展开中已经展开了(CAST_REF2 不是这种情况):

[C++11: 16.3.4/2]: If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.

该规则的目的是禁止无限递归,即使在这种特殊情况下您实际上并没有面临无限递归的风险。

这已在 Stack Overflow 上讨论过 before , 但我不完全确定你现在如何绕过它(除了复制 VARARG )。

关于c++ - C可变参数宏调用另一个可变参数宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24405223/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com