C++ 在静态断言中使用constexpr非成员大小函数

C++ 在静态断言中使用constexpr非成员大小函数,c++,g++,clang++,C++,G++,Clang++,下面是我遇到的一个情况的简化版本 #include <array> template <typename T, size_t BufferSize> constexpr size_t size(const std::array<T, BufferSize>&) { return BufferSize; } template <typename T, size_t BufferSize> constexpr size_t size(con

下面是我遇到的一个情况的简化版本

#include <array>

template <typename T, size_t BufferSize>
constexpr 
size_t size(const std::array<T, BufferSize>&) { return BufferSize; }
template <typename T, size_t BufferSize>
constexpr size_t size(const T (&)[BufferSize]) { return BufferSize; }

template <typename Num, typename Buff>
inline Num func(const Num& num, Buff& buff)
{
    enum 
    { 
        min_size = 6, // Just for test
    };
    static_assert(size(buff) >= min_size, "");
    return num;
}

int main()
{
    //std::array<char, 8> buff;
    char buff[8];
    return func(7U, buff);   
}
我可以假设clang是正确的,因为size函数的输入参数不是constexpr。另一方面,参数本身并没有真正被使用


因此,我的问题是,根据标准,哪种编译器是正确的?

由于g++可以完成这项工作,因此必须提供必要的编译时信息,因此dang是错误的。顺便说一下,std::tuple_size IIRC给出了std::array的编译时大小。@Alf:这种推理是不合理的。允许编译器在编译时根据“仿佛”规则优化函数调用,但这并不能使其成为常量表达式。如果删除constexpr,这一点就会变得很清楚。@MikeSeymour这不是问题所在。这里调用了一个constexpr函数,其参数为替换后生成一个常量表达式。问题在于调用函数之前发生的事情。但是你的结论是正确的:如果表达式不是常量表达式,那么它就不能以这样的方式传递给函数,即函数的结果是常量表达式。@hvd:好的,我将把细节问题留给语言律师来解决。抱歉打扰了。@Cheersandhth.-Alf我知道std::tuple\u的大小。我这样做是因为,据我所知,有人提议设立这样一个功能-。另外,我需要它同时适用于std::array和c-array类型。
error: static_assert expression is not an integral constant expression
    static_assert(size(buff) >= min_size, "");
                  ~~~~~^~~~~~~~~~~~~~~~~