gpt4 book ai didi

c++ - 同一表达式中多个参数包的多次展开

转载 作者:可可西里 更新时间:2023-11-01 16:19:27 30 4
gpt4 key购买 nike

请问下面的代码是否有效

我想知道在一个表达式中多次扩展参数包的可能性。

#include <iostream>
#include <tuple>

class ExpandWithConstructor
{
public:
template <typename ... T>
ExpandWithConstructor( T... args) { }
};

template <typename T>
int PrintArgs( T arg )
{
std::cout << arg << ", ";
return 0;
}

template <typename Head, typename ... T>
class DebugPrinter: public DebugPrinter<T...>
{
public:
DebugPrinter() { }

template< typename ...Y>
DebugPrinter( Y ... rest )
{
std::cout << "Construction of: " << __PRETTY_FUNCTION__ << " Values: " ;
ExpandWithConstructor{PrintArgs( rest)...};
std::cout << std::endl;
}

};

template <typename Head>
class DebugPrinter< Head >
{
public:
};

template <typename ... T>
class TypeContainer: public std::tuple<T...>
{
public:
TypeContainer(T... args):std::tuple<T...>(args...){};
};

template <typename... T1> class CheckVariadic;

template <typename... T1, typename ...T2>
class CheckVariadic< TypeContainer<T1...>, TypeContainer<T2...>> :
public DebugPrinter< T1, T2, T1...>...
{
public:
CheckVariadic( T1... args1, T2... args2, T1... args3): DebugPrinter< T1, T2, T1...>(args1, args2..., args1)... {}
};


int main()
{
CheckVariadic< TypeContainer<int,float>, TypeContainer<char, void*>> checkVariadic1{ 1,2.2,'c',(void*)0xddddd,5,6.6,};
}

如您所见,代码使用了: DebugPrinter< T1, T2, T1...>...

如果 T1 是“int,float”,T2 是“char,void*”扩展到

DebugPrinter< T1, T2, int, float>...

扩展为

DebugPrinter< int, char, int, float>
DebugPrinter< float, void*, int, float>

同样的扩展还有:

 DebugPrinter< T1, T2, T1...>(args1, args2..., args1)...

代码使用 clang3.3 编译,但不能使用 gcc4.8.1 编译,所以我想问一下代码是否有效。

更新:gcc 7.2 仍然没有编译代码。

最佳答案

是的,您的代码完全有效。包扩展由一个模式和一个省略号组成,可以出现在另一个包扩展的模式中。在标准的第 §14.5.3/5 段中,您会发现:

[...] An appearance of the name of a parameter pack is only expanded by the innermost enclosing pack expansion. The pattern of a pack expansion shall name one or more parameter packs that are not expanded by a nested pack expansion; [...]

包扩展可以在 §14.5.3/4 中提到的任何上下文中使用。以你的例子为例:

DebugPrinter< T1, T2, T1...>...

两个包扩展都是有效的。第一个的上下文是 template-argument-list,而第二个出现在 base-specifier-list 中。

标准文本提供的例子:

template<class ... Args>
void g(Args ... args) { // OK: Args is expanded by the function
// parameter pack args
f(const_cast<const Args*>(&args)...); // OK: “Args” and “args” are expanded
f(5 ...); // error: pattern does not contain any
// parameter packs
f(args); // error: parameter pack “args” is not
// expanded
f(h(args ...) + args ...); // OK: first “args” expanded within h,
// second “args” expanded within f
}

关于c++ - 同一表达式中多个参数包的多次展开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18382002/

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