gcc和clang对constexpr功能不一致

min*_*lus 6 c++ gcc clang constexpr c++14

std::array从生成器函数编写一个简单的编译时工厂,我偶然发现:clang ++ 3.5.1和g ++ 4.9.2不同意函数是否constexpr存在.

代码(这是c ++ 14!):

#include <array>
#include <utility>

    template <class T, std::size_t N, class GenType, std::size_t... I> 
    constexpr std::array<T, N>
make_array_impl (GenType gen, std::index_sequence <I...>) 
{
    return {{ gen (I)... }};
}

    template <class T, std::size_t N, class GenType> 
    constexpr std::array<T, N>
make_array (GenType gen)
{
    return make_array_impl <T, N> (
            gen, 
            std::make_index_sequence <N> {}
    );
}

    constexpr int
generator_const (std::size_t /* index */)
{
    return 1;
}

    constexpr auto
a = make_array <int, 3> (generator_const);

static_assert (a.size () == 3, "");
static_assert (a[0] == 1, "");
static_assert (a[1] == 1, "");
static_assert (a[2] == 1, "");

int main () {}
Run Code Online (Sandbox Code Playgroud)

用g ++编译:

migou ~ % g++ -std=c++14 ex.cpp  
ex.cpp:28:41:   in constexpr expansion of ‘make_array<int, 3ul, int (*)(long unsigned int)>(generator_const)’
ex.cpp:18:5:   in constexpr expansion of ‘make_array_impl<int, 3ul, int (*)(long unsigned int), {0ul, 1ul, 2ul}>(gen, (std::make_index_sequence<3ul>{}, std::make_index_sequence<3ul>()))’
ex.cpp:8:21: error: expression ‘generator_const’ does not designate a constexpr function
 return {{ gen (I)... }};
Run Code Online (Sandbox Code Playgroud)

使用clang ++它编译得很好.我可以继续考虑这个有效的g ++ 14(因此g ++有问题吗?)?

Tem*_*Rex 2

constexpr正如 @Casey 在评论中正确指出的那样,关于 或其他聚合的隐式构造函数的 -ness没有任何模糊之处std::array

\n\n
\n

12.1 构造函数[class.ctor]

\n\n

5 当使用 odr (3.2) 创建其类类型 (1.8) 的对象时,或在其第一个对象之后显式默认时,默认且未定义为已删除的默认构造函数是隐式定义的。宣言。隐式定义的默认构造函数执行\n 类的初始化集,该初始化集将由用户为该类编写的默认构造函数执行,\n 没有构造函数初始化器 (12.6.2) 和空复合语句。如果用户编写的默认构造函数格式错误,则程序格式错误。如果用户编写的默认构造函数满足构造函数constexpr(7.1.5) 的要求,则隐式定义的默认构造函数为constexpr在隐式定义类的默认构造函数之前,其基类及其非静态数据成员的所有非用户提供的默认构造函数都应已隐式定义。[ 注意:\n 隐式声明的默认构造函数具有\n 异常规范 (15.4)。显式默认定义可能有隐式异常规范,请参阅 8.4。\xe2\x80\x94结束注]

\n
\n\n

这个问题已在最新的 gcc HEAD 5.0.0 20150217 中得到修复,请参阅此实时示例,并且已经在 Clang 中工作了近一年半了(自 3.4 版本 IIRC 以来,请参阅此问答)。

\n