问题描述
我不明白为什么会这样:
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");