Clang 3.7.0 complains that the class is not a literal because it is not an aggregate and does not have constexpr constructors

The following code compiles in GCC (4.9.3) and VC ++ (19.00.23506), but gives this error in Clang (3.7.0).

error: constexpr function return type 'Foo' is not a literal type

note: 'Foo' is not literal because it is not a collection and does not have constexpr constructors other than copy or move constructors

the code:

#include <iostream>
#include <vector>

struct Foo
{
    std::vector<int> m_vec;
    Foo(const int *foo, std::size_t size=0):m_vec(foo, foo+size)
    {;}
    //Foo(const std::initializer_list<int> &init):m_vec{init}
    //{;}
};


template <std::size_t N>
constexpr Foo make_fooArray(const int (&a)[N]) noexcept
{
    return {a,N};
}


int main()
{
    Foo f{ make_fooArray({1,2,3}) };

    for (auto i : f.m_vec)
        std::cout<< i <<" ";
    std::cout<<std::endl;
}

The code works on the registry:

GCC and VC

Clang

Can you clarify if this is a compiler error or am I missing something? What does the C ++ 11 standard say?


Here is another case where it compiles in GCC and VC, but not in Clang.

#include <iostream>

template <typename T, std::size_t N>
constexpr std::size_t sizeOf_fooArray(const T (&)[N]) noexcept
{
    return N;
}

int main()
{
    std::cout<< sizeOf_fooArray({16,20,53,87,54,7}) <<std::endl;
}

, int [] initializer_list, .

#include <iostream>

template <typename T, std::size_t N>
constexpr std::size_t sizeOf_fooArray(const T (&)[N]) noexcept
{
    return N;
}

using intArray = int[]; //Added

int main()
{
    std::cout<< sizeOf_fooArray(intArray{16,20,53,87,54,7}) <<std::endl;
}
+4
1

.

, , , constexpr, - . , constexpr , . :

template <typename T> constexpr T f(T v) { return v; }

f<int> f<std::string> , f<std::string> .

, , , , constexpr, , . , , .

, , . .

[dcl.constexpr] p6:

constexpr - constexpr constexpr, - constexpr constexpr, . constexpr constexpr , ; .

+8

Source: https://habr.com/ru/post/1660494/


All Articles