Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从C+中删除constexpr+;14模板专业化?_C++_Gcc_Clang_Template Specialization_Constexpr - Fatal编程技术网

C++ 从C+中删除constexpr+;14模板专业化?

C++ 从C+中删除constexpr+;14模板专业化?,c++,gcc,clang,template-specialization,constexpr,C++,Gcc,Clang,Template Specialization,Constexpr,基本问题是,是否可以从专用模板方法中添加或删除constexpr 让我们假设以下代码: //this is my general vector template with a constexpr default ctor template<typename T, typename STORE> struct alignas(16) vec { union { STORE st; struct { T x; T y; T z; T w; };

基本问题是,是否可以从专用模板方法中添加或删除constexpr

让我们假设以下代码:

//this is my general vector template with a constexpr default ctor
template<typename T, typename STORE>
struct alignas(16) vec {
    union {
        STORE st;
        struct { T x; T y; T z; T w; };
    };

    inline explicit constexpr vec() noexcept :
        x{0}, y{0}, z{0}, w{0} {
    }
};

//and this is the SSE enabled version, where we cannot use
//constexpr because of _mm_setzero_ps, so let's remove it...
template<>
inline vec<float, __m128>::vec() noexcept :
    st(_mm_setzero_ps()) {
}
//这是我的常规向量模板,带有一个constexpr默认构造函数
模板
结构alignas(16)vec{
联合{
商店街;
结构{Tx;Ty;Tz;Tw;};
};
内联显式constexpr vec()noexcept:
x{0},y{0},z{0},w{0}{
}
};
//这是支持SSE的版本,我们不能使用
//constexpr因为_mm_setzero_ps,所以让我们删除它。。。
模板
内联向量::向量()无例外:
st(_mm_setzero_ps()){
}
GCC编译它没有问题,但是clang抱怨“constexpr声明之后是'vec'的非constexpr声明”。我想知道哪个编译器做得对,为什么。。?(到目前为止,我无法测试MSVC)


编辑:因为人们对复制和粘贴错误非常挑剔,所以我更正了代码以便编译。

如标准草案7.1.5中的注释所述,它似乎是有效的代码

7.1.5 constexpr说明符[dcl.constexpr]

1 constexpr说明符仅适用于变量或变量的定义 变量模板,函数或函数模板的声明, 或者声明一个文本类型的静态数据成员(3.9)。如果 函数或函数模板的任何声明都有一个constexpr 说明符,则其所有声明都应包含constexpr 说明符。[注意:显式专门化可以不同于 关于constexpr说明符的模板声明。-结束 注][注:函数参数不能声明为constexpr.-end 注]


所以gcc似乎是正确的

如标准草案7.1.5中的注释所述,它似乎是有效代码

7.1.5 constexpr说明符[dcl.constexpr]

1 constexpr说明符仅适用于变量或变量的定义 变量模板,函数或函数模板的声明, 或者声明一个文本类型的静态数据成员(3.9)。如果 函数或函数模板的任何声明都有一个constexpr 说明符,则其所有声明都应包含constexpr 说明符。[注意:显式专门化可以不同于 关于constexpr说明符的模板声明。-结束 注][注:函数参数不能声明为constexpr.-end 注]


所以gcc似乎是正确的

目前,每个编译器在编译时都会遇到问题。忘记语法错误,MSVC也不允许。但是,显式专门化
vec
确实允许您编写非constexpr构造函数。看起来编译器之间的比例相当:Clang和MSVC拒绝它,GCC和EDG前端在严格模式下接受它。我倾向于认为它应该被拒绝:它是类模板成员的显式专门化,用于该模板的隐式实例化。类模板的隐式实例化涉及实例化成员函数的声明,因此
constepr
已经存在。[14.7.3p6]中的标准中有一个有点相关的例子(涉及
enum
s,但我认为原理是一样的)。这里没有真正的理由使用专门化。只需要一个委托构造函数。@T.C.但是我想在这里做编译器的工作(有3个方法体而不是2个),如果我添加更多的专门化(例如vec.Not quite),它会变得非常混乱。标记分派解决方案不会改变以下事实:在模板的所有实例化中,默认构造函数仍然是constexpr。对于
vec
,实例化的默认构造函数定义不满足constexpr构造函数的要求(它委托给非constexpr构造函数),因此它不能出现在常量表达式中,但仍被视为constexpr。根据[7.1.5p6]的规定,这是允许的,只要存在至少一个其他模板参数组合,并且专门化确实满足这些要求。目前,每个编译器在编译这些参数时都会遇到问题。忘记语法错误,MSVC也不允许。但是,显式专门化
vec
确实允许您编写非constexpr构造函数。看起来编译器之间的比例相当:Clang和MSVC拒绝它,GCC和EDG前端在严格模式下接受它。我倾向于认为它应该被拒绝:它是类模板成员的显式专门化,用于该模板的隐式实例化。类模板的隐式实例化涉及实例化成员函数的声明,因此
constepr
已经存在。[14.7.3p6]中的标准中有一个有点相关的例子(涉及
enum
s,但我认为原理是一样的)。这里没有真正的理由使用专门化。只需要一个委托构造函数。@T.C.但是我想在这里做编译器的工作(有3个方法体而不是2个),如果我添加更多的专门化(例如vec.Not quite),它会变得非常混乱。标记分派解决方案不会改变以下事实:在模板的所有实例化中,默认构造函数仍然是constexpr。对于
vec
,实例化的默认构造函数定义不满足constexpr构造函数的要求(它委托给非constexpr构造函数),因此它不能出现在常量表达式中,但仍被视为constexpr。根据[7.1.5p6],这是允许的,只要存在至少一个其他模板参数组合,且专门化确实满足要求。这里的问题是
vec
是隐式的