如何使这些折叠表达式起作用?

问题描述

我不明白为什么会这样:

template <typename ... Types>
void func()
{

    (std::cout << typeid(Types).name(),...) ; // Syntax error,unexpected token '...',expected 'expression'
    (static_assert(std::is_integral_v<Types>,"Type must be integral type"),...); // Syntax error: unexpected token 'static_assert',expected 'expression'
}
int main()
{
    func<int,short>();

}

我的理解是编译器基本上应该去:

(static_assert(std::is_integral_v<Types>,"Error message"),...)

逗号是一个运算符,运算符之前的内容应该为参数包中的每种类型重复。为什么这不起作用?

解决方法

运算符 << 要求将 ... 置于运算符之间。 static_assert 不是表达式,因此 fold 表达式无济于事。解决方法是使用单个 static_assert 创建专用检查函数并调用此函数折叠内置运算符 , 调用:

#include <iostream>
#include <typeinfo>
#include <type_traits>

template<typename x_Type>
constexpr void is_integral_check(void) noexcept
{
    static_assert(::std::is_integral_v<x_Type>,"Type must be an integral type.");
    return;
}

template<typename ... x_Types>
void func()
{
    (::std::cout << ... << typeid(x_Types).name());
    (is_integral_check<x_Types>(),...);
}

int main()
{
    func<int,short>();
}

https://godbolt.org/z/5G4xxc15s

,

折叠表达式不能包含优先级低于强制转换的(无括号)运算符。

所以要么添加括号:((std::cout << typeid(Types).name()),...);

或者将 << 折叠起来:(std::cout << ... << typeid(Types).name());


至于static_assert,它是一个声明而不是一个表达式,所以你不能折叠它。

使用一个大的 static_assert,带有一个 && 折叠表达式:

static_assert((std::is_integral_v<Types> && ...),"Type must be integral type")
,

您的第一个语法错误可能是由于未使用 C++17 作为折叠表达式在那里引入的结果。 我尝试使用 C++14 编译您的代码,但遇到了相同的语法错误。

(std::cout << typeid(Types).name(),...);  // needs C++17,Syntax error with C++14

第二个可以这样改写:

static_assert((std::is_integral_v<Types> && ...),"Type must be integral type");

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...