同一表达式中多个参数包的多次展开
Multiple expansions of multiple parameter packs in the same expression
我想问以下代码是否有效。
我想知道在一个表达式中多次扩展参数包的可能性。
#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,};
}
正如您所看到的,代码使用:调试打印机<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/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
}
相关文章:
- 概念中的cv限定符需要表达式参数列表
- 在函数中使用 const int size 参数创建数组会在 Visual Studio 中抛出错误 C++:表达式的计
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 使用自动推导的 lambda 参数作为常量表达式
- 编译器是否强制根据模板参数计算表达式?
- 错误:参数中无效地使用了无效表达式
- 将折叠表达式传递给可变参数模板
- 为什么带有指针子对象的文字类类型的 constexpr 表达式不能是非类型模板参数
- C++: priority_queue:模板参数中的 lambda 表达式
- 容器如何处理 lambda 表达式的参数
- 在C++ Lambda 表达式中,为什么人们更喜欢按值捕获而不是作为参数传递?
- 整体模板参数。错误:在常量表达式中使用'this'
- 我可以std::在fold表达式中转发参数吗
- 折叠表达式模板参数推导/替换失败
- 折叠表达式和参数包:static_assert 内 Args&& 和 Args 之间的区别
- C++:从捕获函数参数的函数返回 lambda 表达式
- 是否可以使用带有模板化参数的特征块表达式作为左值?
- 编译器在传递 const 变量时返回错误:模板参数不是常量表达式
- 表达式参数在 C++ 中有什么用
- 类表达式参数定义不正确