2016-03-03 107 views
8

cppreference.comstatic_assert和英特尔C++编译器

静态断言声明可以在块范围出现(作为块 声明)和类体内(作为成员声明)

好了,现在我有以下代码:

struct foo_t 
{ 
    static constexpr std::size_t maxAlignment() 
    { 
     // This is just a sample; I removed real code from this method. 
     return std::max(alignof(__m128), __alignof(__m256)); 
    } 

    static_assert(0 == ((maxAlignment() -1) & maxAlignment()), "some message"); 
}; 

氖ither MSVC 2015或英特尔C++ 16.0.2编译此代码(前者显示“错误C2131:表达式未计算为常量”,后者显示“函数调用在常量表达式中必须具有常量值”错误,并指向调用maxAlignment in static_assert)。

但MSVC 2015更新1 编译下面的代码,而英特尔C++ 16.0.2

template <typename T, std::size_t Alignment> 
struct foo_t 
{ 
    static constexpr std::size_t maxAlignment() 
    { 
     return std::max(std::alignment_of<T>::value, Alignment); 
    } 

    static_assert(0 == ((maxAlignment() -1) & maxAlignment()), "some message"); 
}; 

foo_t<__m128, 16> foo {}; 
// foo_t<__m128, 33> boo {}; // here `static_assert` will stop compilation 

(所以,MSVC可以处理static_assert当它是一个模板类中body)

但是,下面的代码由两个编译器成功编译(static_assert在类体外;它出现在块范围内):

struct foo_t 
{ 
    static constexpr std::size_t maxAlignment() 
    { 
     return std::max(alignof(__m128), __alignof(__m256)); 
    } 
}; 

static_assert(0 == ((foo_t::maxAlignment() -1) & foo_t::maxAlignment()), "some message"); 

我的问题是:我错过了什么或者是英特尔C++编译器的错误?

+0

_“MSVC 2015成功编译上面的代码。”_不在我的计算机上:_“错误C2131:表达式未计算为常量”_我在Intel和GCC上得到了相同的结果。 – ZDF

+0

@ZDF我有'更新1' - 可能会导致MSVC 2015编译该代码(当'static_assert'在类体内部时)。 –

+1

编译器现在已经在'constexpr'支持的地方;我们在GCC和MSVC中遇到了代码生成的错误。 – Crashworks

回答

1

如果我记得它的权利constexpr函数不能使用,直到他们完全定义和类成员constexpr函数未定义,直到定义类,它意味着你不能在类中使用constexpr成员函数 - 范围static_assert它定义了这个功能。

但是,你可以使这个功能独立(它已经是静态的),它会完成这项工作。它应该到处编译。

+0

函数是'static',是的,但它取决于模板的参数。 –

+0

@RuslanGaripov,独立函数也可以有模板参数 – ixSci

+0

好的,非常感谢! –