使用对齐符展开参数包的语法是什么?
What is the syntax for parameter pack expansion with alignas?
我试图在对齐说明符中展开参数包。我的语法不对。下面是一个简单的例子:
#include <cstdint>
#include <tuple>
template <typename... Ts>
struct C
{
using Tuple_Type = std::tuple <Ts...>;
void f()
{
uint8_t i1;
uint8_t i2 alignas (2);
uint8_t i3 alignas (typename std::tuple_element<0, Tuple_Type>::type);
uint8_t i4 alignas (Ts...);
}
};
//template class C <>; // not compatible with i3 declaration above
template class C <uint64_t>;
使用gcc 4.8.3编译失败:
foo.cpp: In member function 'void C<Ts>::f()':
foo.cpp:14:31: error: expected ')' before '...' token
uint8_t i4 alignas (Ts...);
^
foo.cpp:14:31: error: expected ')' before '...' token
foo.cpp:14:31: error: expected initializer before '...' token
c++标准([dcl.align])说"带有省略号的对齐说明符是一个包扩展",所以看起来应该可以做我想做的事情。
我一直无法找到这种参数包扩展的示例,并且我搜索gcc中可能存在的错误也没有找到任何东西。
这看起来像GCC中的bug c++/59012,在GCC 5.2中修复了。你的例子在Clang 3.5.1下可以很好地编译。
有趣的是,如果您完全省略省略号,GCC会正确地抱怨参数包:
14 : error: parameter packs not expanded with '...':
uint8_t i4 alignas(Ts);
^
在GCC 4.8.x中,你不可能(轻松地)让它工作;这太愚蠢了。然而,在GCC 4.9和更高版本中,您可以使用以下想法,这是我从ecatmur的建议中改编的,使用constexpr max
。
template<int...>
struct maxInts {};
template<int A, int B, int... Cs>
struct maxInts<A, B, Cs...> {
const static int value = A > B ? maxInts<A, Cs...>::value : maxInts<B, Cs...>::value;
};
template<int A, int B>
struct maxInts<A, B> {
const static int value = A > B ? A : B;
};
template<int A>
struct maxInts<A> {
const static int value = A;
};
这只是让您在编译时获得任意整数数量的最大值,如:
const int x = maxInts<1, 2, 3, 4, 5>::value; // x == 5
现在你麻烦的alignas
看起来像这样:
uint8_t i4 alignas(maxInts<alignof(Ts)...>::value);
语法正确;自5.2.0以来,GCC仅在对齐说明符内实现包扩展。59012 - alignas不支持参数包扩展。
你可以尝试使用alignas (std::aligned_union_t<1, Ts...>)
,但不幸的是gcc从5.1.0开始只实现了aligned_union
,所以它只是稍微好一点。
如果你想使用旧的编译器,你必须自己编写constexpr max
函数(因为旧版本的gcc也不实现constexpr max(std::initializer_list<T>)
)并自己计算最大对齐,如alignas(max({alignof(T)...}))
。
相关文章:
- C++避免重复声明的语法是什么
- 使用基类指针调用基类的值构造函数的语法是什么?
- 这行/语法是什么意思?
- 初始化对象以在 C++08 中作为参数传递的首选语法是什么?
- 将引用绑定到指针的语法是什么?(各种)
- 这个typedef和转换运算符语法是什么意思
- 此语法是什么意思.(::*).
- 将显式指定的函数模板重载作为模板参数传递的正确语法是什么?
- 使用 pybind11 绑定 typedef 类型的正确语法是什么?
- 将此类传递给引用的正确语法是什么?
- 带有约束的可变参数模板的'requires'表达式的语法是什么?
- 在TensorFlow C++中用于feed_dict的语法是什么?
- 调用模板化类内的枚举类枚举器的正确语法是什么
- 返回没有 typedef 的成员函数指针的语法是什么?
- 将强制转换运算符重载到 std::map 的正确语法是什么
- 这种增量语法是什么意思
- 返回结构的方法的正确语法是什么
- C 中的(*)语法是什么意思
- 堆栈(int = 10),这个语法是什么意思(C++)
- variadic模板阵列参考参数的语法是什么?