以下代码:
#include<iostream>
#include<array>
using std::size_t;
using std::array;
//#define INIT_BY_HAND 1
#define CONSTEXPR 1
#ifdef CONSTEXPR
constexpr
#endif
size_t accumulator_count()
{
constexpr size_t nb_rows{2};
constexpr size_t nb_cols{2};
size_t nb{0};
for(size_t k = 0; k < nb_rows; ++k)
{
array<size_t,nb_cols> acc{}; // value initialization: expect both elements to be zero
//for const_cast/static_cast see http://stackoverflow.com/questions/34199774/why-is-non-const-stdarrayoperator-not-constexpr
#ifdef INIT_BY_HAND
for(size_t j = 0; j < nb_cols; ++j)
const_cast<size_t&>(static_cast<array<size_t,nb_cols> const&>(acc)[j]) = 0;
#endif
if(k == 0)
const_cast<size_t&>(static_cast<array<size_t,nb_cols> const&>(acc)[0]) = 1;
if(k == 1)
const_cast<size_t&>(static_cast<array<size_t,nb_cols> const&>(acc)[nb_cols-1]) = 1;
for(size_t j = 0; j < nb_cols; ++j)
nb += size_t(static_cast<array<size_t,nb_cols> const&>(acc)[j] != 0);
}
return nb;
}
int main()
{
#ifdef CONSTEXPR
constexpr
#endif
size_t nb{accumulator_count()};
std::cout << "nb: " << nb << std::endl;
}
在gcc 5.3.1(-Wall -std = c ++ 14)上编译时没有警告,但它会产生错误的输出3.
没有constexpr(注释掉#define CONSTEXPR 1行)它正确输出2.
手动初始化(#define INIT_BY_HAND 1行注释),它正确输出2.
使用clang 3.8.0编译,正确输出2。
问题:此代码是否符合c ++ 14标准或我错过了什么?
答案 0 :(得分:3)
g ++ 6.3.0和clang ++ 3.8.0都编译并生成值2。
这有力地表明g ++ 5.3.1出错了。
暂且不说:
namespace notstd {
template<class T, std::size_t N>
constexpr T& constexpr_get( std::array<T, N>& arr, std::size_t I ) {
return const_cast<T&>(const_cast<std::array<T,N> const&>(arr)[I]);
}
struct at {
std::size_t I = 0;
constexpr at(std::size_t i):I(i){}
template<class T, std::size_t N>
friend constexpr T&
operator->*( std::array<T, N>& arr, at a ) {
return constexpr_get(arr, a.I);
}
// optional
template<class T, std::size_t N>
friend constexpr T const&
operator->*( std::array<T, N> const& arr, at a ) {
return arr[a.I];
}
};
}
和using notstd::at
为您提供了比所有演员更漂亮的中缀方式:
arr->*at(0) = 1;
(谁说我们在C ++中还没有扩展方法?)