C++11 constexpr模板函数不';t将成员数组大小视为常量表达式

C++11 constexpr模板函数不';t将成员数组大小视为常量表达式,c++11,clang,sizeof,constexpr,static-assert,C++11,Clang,Sizeof,Constexpr,Static Assert,当ArrayCount是一个模板时,clang和gcc都无法编译下面的代码。这似乎是错误的,特别是考虑到ArrayCount解决方案的大小是有效的。ArrayCount的模板版本通常是一个更好的解决方案,但它在这里遇到了障碍,而且constexpr似乎没有实现其承诺的精神 #if 1 template<typename T, size_t N> constexpr size_t ArrayCount(T (&)[N]) { retu

当ArrayCount是一个模板时,clang和gcc都无法编译下面的代码。这似乎是错误的,特别是考虑到ArrayCount解决方案的大小是有效的。ArrayCount的模板版本通常是一个更好的解决方案,但它在这里遇到了障碍,而且constexpr似乎没有实现其承诺的精神

#if 1
    template<typename T, size_t N> 
    constexpr size_t ArrayCount(T (&)[N]) 
    {
        return N;
    }
    // Results in this (clang): error : static_assert expression is not an integral constant expression
    // Results in this (gcc): error: non-constant condition for static assertion, 'this' is not a constant expression
#else
    #define ArrayCount(t) (sizeof(t) / sizeof(t[0]))
    // Succeeds
#endif

struct X
{
    int x[4];
    X() { static_assert(ArrayCount(x) == 4, "should never fail"); }
};
#如果1
模板
constexpr size\u t数组计数(t(&)[N])
{
返回N;
}
//结果如下(铿锵):错误:静态_断言表达式不是整型常量表达式
//结果如下(gcc):错误:静态断言的非常量条件,“this”不是常量表达式
#否则
#定义数组计数(t)(sizeof(t)/sizeof(t[0]))
//成功
#恩迪夫
结构X
{
int x[4];
X(){static_assert(ArrayCount(X)==4,“应该永不失败”);}
};

我觉得这段代码无法编译是有道理的,因为ArrayCount是一个函数,它采用了非
constepr
参数。根据该标准,我认为这意味着
ArrayCount
必须作为一个非
constepr
函数

当然,还有一些变通办法。我脑海中可以想到两个(一个是根据另一个实现的):

模板结构ArrayCount;
模板
结构数组计数{
静态大小\u t const size=N;
};
模板
constexpr大小\u t数组计数2(){
返回ArrayCount::size;
}
结构X{
int x[4];
X(){
静态_断言(ArrayCount::size==4,“应该永远不会失败”);
静态_断言(ArrayCount2()==4,“应该永远不会失败”);
}
};

它确实意味着在您可能不想使用的时候必须使用
decltype()
,但它确实打破了采用非
constepr
参数的形式限制。

我认为这段代码将无法编译,因为ArrayCount是一个采用非
constepr
参数的函数。根据该标准,我认为这意味着
ArrayCount
必须作为一个非
constepr
函数

当然,还有一些变通办法。我脑海中可以想到两个(一个是根据另一个实现的):

模板结构ArrayCount;
模板
结构数组计数{
静态大小\u t const size=N;
};
模板
constexpr大小\u t数组计数2(){
返回ArrayCount::size;
}
结构X{
int x[4];
X(){
静态_断言(ArrayCount::size==4,“应该永远不会失败”);
静态_断言(ArrayCount2()==4,“应该永远不会失败”);
}
};

它确实意味着在您可能不想使用时必须使用
decltype()
,但它确实打破了采用非
constepr
参数的形式限制。

正确的解决方案不使用自制代码,而是使用一个简单的类型特征:

int a[] = {1, 2, 3};

#include <type_traits>

static_assert(std::extent<decltype(a)>::value == 3, "You won't see this");
inta[]={1,2,3};
#包括
静态_断言(std::extent::value==3,“您不会看到这个”);

正确的解决方案不使用自制代码,而是使用一个简单的类型特征:

int a[] = {1, 2, 3};

#include <type_traits>

static_assert(std::extent<decltype(a)>::value == 3, "You won't see this");
inta[]={1,2,3};
#包括
静态_断言(std::extent::value==3,“您不会看到这个”);

Clang/GCC版本?哪个stdlib?Clang/GCC版本?哪个标准数据库?